diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2012-03-10 19:22:10 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2012-03-10 19:22:10 +0000 |
commit | 4eaa4e42093e5524d9552d8fa312c214524b6bb4 (patch) | |
tree | a251d57ee92d9c779fe4455c583be0ed90e69a43 /qpid/java/broker/src/main/java/org/apache/qpid | |
parent | 92be7e8f3163c048a8642d2deeaa921bbb65dc9c (diff) | |
download | qpid-python-rg-amqp-1-0-sandbox.tar.gz |
NO-JIRA : AMQP-1-0 sandbox updates - merge from trunkrg-amqp-1-0-sandbox
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rg-amqp-1-0-sandbox@1299257 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker/src/main/java/org/apache/qpid')
333 files changed, 6234 insertions, 8300 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java b/qpid/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java deleted file mode 100644 index 0b63c68854..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java +++ /dev/null @@ -1,188 +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.configuration; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.commons.cli.PosixParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; - -public class Configuration -{ - public static final String QPID_HOME = "QPID_HOME"; - - final String QPIDHOME = System.getProperty(QPID_HOME); - - private static Logger _devlog = LoggerFactory.getLogger(Configuration.class); - - public static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml"; - public static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; - - protected final Options _options = new Options(); - protected CommandLine _commandLine; - protected File _configFile; - - - public Configuration() - { - - } - - public void processCommandline(String[] args) throws InitException - { - try - { - _commandLine = new PosixParser().parse(_options, args); - } - catch (ParseException e) - { - throw new InitException("Unable to parse commmandline", e); - } - - final File defaultConfigFile = new File(QPIDHOME, DEFAULT_CONFIG_FILE); - setConfig(new File(_commandLine.getOptionValue("c", defaultConfigFile.getPath()))); - } - - public void setConfig(File file) - { - _configFile = file; - } - - /** - * @param option The option to set. - */ - public void setOption(Option option) - { - _options.addOption(option); - } - - /** - * getOptionValue from the configuration - * @param option variable argument, first string is option to get, second if present is the default value. - * @return the String for the given option or null if not present (if default value not specified) - */ - public String getOptionValue(String... option) - { - if (option.length == 1) - { - return _commandLine.getOptionValue(option[0]); - } - else if (option.length == 2) - { - return _commandLine.getOptionValue(option[0], option[1]); - } - return null; - } - - public void loadConfig(File file) throws InitException - { - setConfig(file); - loadConfig(); - } - - private void loadConfig() throws InitException - { - if (!_configFile.exists()) - { - String error = "File " + _configFile + " could not be found. Check the file exists and is readable."; - - if (QPIDHOME == null) - { - error = error + "\nNote: " + QPID_HOME + " is not set."; - } - - throw new InitException(error, null); - } - else - { - _devlog.debug("Using configuration file " + _configFile.getAbsolutePath()); - } - -// String logConfig = _commandLine.getOptionValue("l"); -// String logWatchConfig = _commandLine.getOptionValue("w", "0"); -// if (logConfig != null) -// { -// File logConfigFile = new File(logConfig); -// configureLogging(logConfigFile, logWatchConfig); -// } -// else -// { -// File configFileDirectory = _configFile.getParentFile(); -// File logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME); -// configureLogging(logConfigFile, logWatchConfig); -// } - } - - -// private void configureLogging(File logConfigFile, String logWatchConfig) -// { -// int logWatchTime = 0; -// try -// { -// logWatchTime = Integer.parseInt(logWatchConfig); -// } -// catch (NumberFormatException e) -// { -// _devlog.error("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " -// + "a non-negative integer. Using default of zero (no watching configured"); -// } -// -// if (logConfigFile.exists() && logConfigFile.canRead()) -// { -// _devlog.info("Configuring logger using configuration file " + logConfigFile.getAbsolutePath()); -// if (logWatchTime > 0) -// { -// _devlog.info("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every " -// + logWatchTime + " seconds"); -// // log4j expects the watch interval in milliseconds -// DOMConfigurator.configureAndWatch(logConfigFile.getAbsolutePath(), logWatchTime * 1000); -// } -// else -// { -// DOMConfigurator.configure(logConfigFile.getAbsolutePath()); -// } -// } -// else -// { -// System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath()); -// System.err.println("Using basic log4j configuration"); -// BasicConfigurator.configure(); -// } -// } - - public File getConfigFile() - { - return _configFile; - } - - - public static class InitException extends Exception - { - InitException(String msg, Throwable cause) - { - super(msg, cause); - } - } -}
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java index b898e85aa2..2d6f7e0946 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java @@ -35,7 +35,6 @@ 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.AMQMessageHeader; import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.queue.AMQQueue; @@ -50,7 +49,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.TimerTask; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -412,6 +410,11 @@ public class ManagementExchange implements Exchange, QMFService.Listener 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. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java index 709b59588d..69284abc48 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java @@ -22,17 +22,14 @@ package org.apache.qpid.qmf; import org.apache.log4j.Logger; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.transport.codec.BBEncoder; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.virtualhost.VirtualHost; + +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.AMQException; -import org.apache.qpid.management.common.mbeans.ManagedConnection; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.transport.codec.BBDecoder; -import java.util.ArrayList; import java.util.List; public class QMFBrokerRequestCommand extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java index ac01c47fe8..34b2a851dc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java @@ -22,7 +22,6 @@ package org.apache.qpid.qmf; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.codec.BBEncoder; public class QMFBrokerResponseCommand extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java index 3408ff09f4..7d566567a1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java @@ -21,12 +21,10 @@ package org.apache.qpid.qmf; -import org.apache.qpid.server.configuration.ConfiguredObject; - import java.util.Collection; -import java.util.Map; -import java.util.List; import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; abstract public class QMFClass { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java index a956a9bd70..613e1e5978 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java @@ -21,8 +21,6 @@ package org.apache.qpid.qmf; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.codec.BBEncoder; public class QMFClassIndicationCommand extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java index 64edc2f294..5676bb7306 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java @@ -22,15 +22,15 @@ package org.apache.qpid.qmf; import org.apache.log4j.Logger; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; + +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.AMQException; +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.List; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java index 9a25201d4c..397ad4090e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java @@ -21,8 +21,6 @@ package org.apache.qpid.qmf; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.codec.BBEncoder; public class QMFCommandCompletionCommand extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java index d70c12db19..833ccfbca4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.qmf; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.codec.BBEncoder; public abstract class QMFEventCommand<T extends QMFEventClass> extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java index c11e1a9b27..b1f958d4ba 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java @@ -22,15 +22,21 @@ package org.apache.qpid.qmf; import org.apache.log4j.Logger; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; + +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.AMQException; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.transport.codec.BBDecoder; -import java.util.*; +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 { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java index 3248a5aae0..97e74bed89 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java @@ -22,9 +22,13 @@ package org.apache.qpid.qmf; 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.*; +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; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java index 63e8fa6a1e..1d1cd24724 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java @@ -21,12 +21,12 @@ package org.apache.qpid.qmf; -import org.apache.qpid.transport.codec.Encoder; 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; -import java.util.ArrayList; public abstract class QMFMethod<T extends QMFObject> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java index 4001a2a321..1a4ce228b5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java @@ -21,16 +21,16 @@ package org.apache.qpid.qmf; import org.apache.log4j.Logger; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; + +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.AMQException; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.transport.codec.BBDecoder; import java.util.List; import java.util.UUID; -import java.util.ArrayList; public class QMFMethodRequestCommand extends QMFCommand { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java index 681e64b799..63b43475aa 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java @@ -22,8 +22,8 @@ package org.apache.qpid.qmf; import java.util.Collection; -import java.util.Map; import java.util.HashMap; +import java.util.Map; public class QMFPackage { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java index 7053b80655..9c8fa1e2c6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java @@ -21,8 +21,6 @@ package org.apache.qpid.qmf; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.codec.BBEncoder; public class QMFPackageIndicationCommand extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java index 9cacbafcc1..c74c7da252 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java @@ -22,15 +22,15 @@ package org.apache.qpid.qmf; import org.apache.log4j.Logger; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; + +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.AMQException; +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.List; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java index 5748722afe..5314466e2a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java @@ -23,9 +23,8 @@ package org.apache.qpid.qmf; import org.apache.qpid.transport.codec.Encoder; -import java.util.Map; -import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.Map; public class QMFProperty { @@ -68,8 +67,6 @@ public class QMFProperty public void setQMFClass(QMFClass qmfClass) { - /* _map.put(REF_CLASS, qmfClass.getName()); - _map.put(REF_PACKAGE, qmfClass.getPackage().getName());*/ } public void setReferencedClass(String refClass) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java index a1260ed9e6..57c67fa7f6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java @@ -22,16 +22,15 @@ package org.apache.qpid.qmf; import org.apache.log4j.Logger; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.registry.IApplicationRegistry; + +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.AMQException; +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.ArrayList; import java.util.List; public class QMFSchemaRequestCommand extends QMFCommand diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java index fea2430130..4bd0e41989 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java @@ -21,8 +21,6 @@ package org.apache.qpid.qmf; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.codec.BBEncoder; import java.util.Collection; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java index 27345f0a88..900b722886 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java @@ -658,6 +658,11 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable return _obj.getStagingThreshold(); } + public Boolean getMgmtPublish() + { + return true; + } + public Integer getMgmtPubInterval() { return _obj.getManagementPublishInterval(); @@ -678,6 +683,204 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable 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) @@ -1064,6 +1267,96 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable 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(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java index 01a0d9900d..265aa7714e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java @@ -18,16 +18,6 @@ */ package org.apache.qpid.server; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.management.JMException; -import javax.management.MBeanException; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; @@ -39,6 +29,8 @@ 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.exchange.ExchangeType; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.ManagementActor; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.queue.AMQQueue; @@ -48,8 +40,15 @@ import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostImpl; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.ManagementActor; + +import javax.management.JMException; +import javax.management.MBeanException; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** * This MBean implements the broker management interface and exposes the @@ -169,7 +168,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr */ public void createNewExchange(String exchangeName, String type, boolean durable) throws JMException, MBeanException { - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { synchronized (_exchangeRegistry) @@ -213,10 +212,10 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr { // TODO // Check if the exchange is in use. - // boolean inUse = false; + // Check if there are queue-bindings with the exchange and unregister // when there are no bindings. - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { _exchangeRegistry.unregisterExchange(new AMQShortString(exchangeName), false); @@ -256,7 +255,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr throw new JMException("The queue \"" + queueName + "\" already exists."); } - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { AMQShortString ownerShortString = null; @@ -312,7 +311,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr throw new JMException("The Queue " + queueName + " is not a registered queue."); } - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { queue.delete(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index c0ecbb3630..2d2bc5fad7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -20,8 +20,23 @@ */ package org.apache.qpid.server; -import org.apache.log4j.Logger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.UUID; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQMethodBody; @@ -57,10 +72,10 @@ import org.apache.qpid.server.message.MessageMetaData; 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.protocol.AMQConnectionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.InboundMessageAdapter; @@ -75,18 +90,11 @@ import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.subscription.SubscriptionImpl; import org.apache.qpid.server.txn.AsyncAutoCommitTransaction; -import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.LocalTransaction; import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.TransportException; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; - public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder { public static final int DEFAULT_PREFETCH = 4096; @@ -122,7 +130,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm private IncomingMessage _currentMessage; /** Maps from consumer tag to subscription instance. Allows us to unsubscribe from a queue. */ - protected final Map<AMQShortString, Subscription> _tag2SubscriptionMap = new HashMap<AMQShortString, Subscription>(); + private final Map<AMQShortString, Subscription> _tag2SubscriptionMap = new HashMap<AMQShortString, Subscription>(); private final MessageStore _messageStore; @@ -148,7 +156,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm private final AMQProtocolSession _session; private AtomicBoolean _closing = new AtomicBoolean(false); - private final ConcurrentMap<AMQQueue, Boolean> _blockingQueues = new ConcurrentHashMap<AMQQueue, Boolean>(); + private final Set<AMQQueue> _blockingQueues = new ConcurrentSkipListSet<AMQQueue>(); private final AtomicBoolean _blocking = new AtomicBoolean(false); @@ -267,7 +275,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm { throw new AMQSecurityException("Permission denied: " + e.getName()); } - _currentMessage = new IncomingMessage(info); + _currentMessage = new IncomingMessage(info, getProtocolSession().getReference()); _currentMessage.setExchange(e); } @@ -289,26 +297,9 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm _currentMessage.setExpiration(); + _currentMessage.headersReceived(getProtocolSession().getLastReceivedTime()); - MessageMetaData mmd = _currentMessage.headersReceived(getProtocolSession().getLastReceivedTime()); - final StoredMessage<MessageMetaData> handle = _messageStore.addMessage(mmd); - _currentMessage.setStoredMessage(handle); - - routeCurrentMessage(); - - - _transaction.addPostTransactionAction(new ServerTransaction.Action() - { - - public void postCommit() - { - } - - public void onRollback() - { - handle.remove(); - } - }); + _currentMessage.route(); deliverCurrentMessageIfComplete(); } @@ -340,17 +331,41 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm { _actor.message(ExchangeMessages.DISCARDMSG(_currentMessage.getExchange().asString(), _currentMessage.getRoutingKey())); } - } else { + final StoredMessage<MessageMetaData> handle = _messageStore.addMessage(_currentMessage.getMessageMetaData()); + _currentMessage.setStoredMessage(handle); + int bodyCount = _currentMessage.getBodyCount(); + if(bodyCount > 0) + { + long bodyLengthReceived = 0; + for(int i = 0 ; i < bodyCount ; i++) + { + ContentChunk contentChunk = _currentMessage.getContentChunk(i); + handle.addContent((int)bodyLengthReceived, ByteBuffer.wrap(contentChunk.getData())); + bodyLengthReceived += contentChunk.getSize(); + } + } + + _transaction.addPostTransactionAction(new ServerTransaction.Action() + { + public void postCommit() + { + } + + public void onRollback() + { + handle.remove(); + } + }); + _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues), getProtocolSession().getLastReceivedTime()); incrementOutstandingTxnsIfNecessary(); - updateTransactionalActivity(); + updateTransactionalActivity(); + _currentMessage.getStoredMessage().flushToStore(); } } - _currentMessage.getStoredMessage().flushToStore(); - } finally { @@ -377,9 +392,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm try { - - // returns true iff the message was delivered (i.e. if all data was - // received final ContentChunk contentChunk = _session.getMethodRegistry().getProtocolVersionMethodConverter().convertToContentChunk(contentBody); @@ -403,11 +415,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } - protected void routeCurrentMessage() throws AMQException - { - _currentMessage.route(); - } - public long getNextDeliveryTag() { return ++_deliveryTag; @@ -777,20 +784,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm AMQQueue queue = message.getQueue(); - // Our Java Client will always suspend the channel when resending! - // If the client has requested the messages be resent then it is - // their responsibility to ensure that thay are capable of receiving them - // i.e. The channel hasn't been server side suspended. - // if (isSuspended()) - // { - // _logger.info("Channel is suspended so requeuing"); - // //move this message to requeue - // msgToRequeue.add(message); - // } - // else - // { - // release to allow it to be delivered - // Without any details from the client about what has been processed we have to mark // all messages in the unacked map as redelivered. message.setRedelivered(); @@ -1116,7 +1109,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm AMQMessage message = new AMQMessage(incomingMessage.getStoredMessage()); message.setExpiration(incomingMessage.getExpiration()); - message.setClientIdentifier(_session); + message.setConnectionIdentifier(_session.getReference()); return message; } @@ -1370,7 +1363,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm public void block(AMQQueue queue) { - if(_blockingQueues.putIfAbsent(queue, Boolean.TRUE) == null) + if(_blockingQueues.add(queue)) { if(_blocking.compareAndSet(false,true)) @@ -1394,6 +1387,16 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } + public boolean onSameConnection(InboundMessage inbound) + { + if(inbound instanceof IncomingMessage) + { + IncomingMessage incoming = (IncomingMessage) inbound; + return getProtocolSession().getReference() == incoming.getConnectionReference(); + } + return false; + } + private void flow(boolean flow) { MethodRegistry methodRegistry = _session.getMethodRegistry(); @@ -1623,4 +1626,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } + public int compareTo(AMQSessionModel session) + { + return getId().toString().compareTo(session.getID().toString()); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java index e3d8747d72..da26fe1fc4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java @@ -20,24 +20,10 @@ */ package org.apache.qpid.server; -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.logging.*; - -import javax.net.ssl.SSLContext; - +import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.apache.log4j.xml.QpidLog4JConfigurator; + import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration; import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean; @@ -58,10 +44,33 @@ 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 javax.net.ssl.SSLContext; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.logging.ConsoleHandler; +import java.util.logging.FileHandler; +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + public class Broker { + private static final Logger LOGGER = Logger.getLogger(Broker.class); + private static final int IPV4_ADDRESS_LENGTH = 4; private static final char IPV4_LITERAL_SEPARATOR = '.'; + private volatile Thread _shutdownHookThread; private java.util.logging.Logger FRAME_LOGGER; private java.util.logging.Logger RAW_LOGGER; @@ -79,7 +88,14 @@ public class Broker public void shutdown() { - ApplicationRegistry.remove(); + try + { + removeShutdownHook(); + } + finally + { + ApplicationRegistry.remove(); + } } public void startup() throws Exception @@ -93,6 +109,7 @@ public class Broker { CurrentActor.set(new BrokerActor(new SystemOutMessageLogger())); startupImpl(options); + addShutdownHook(); } finally { @@ -185,32 +202,37 @@ public class Broker bindAddr = serverConfig.getBind(); } - InetAddress bindAddress = null; + InetAddress bindAddress; if (bindAddr.equals(WILDCARD_ADDRESS)) { - bindAddress = new InetSocketAddress(0).getAddress(); + bindAddress = null; } else { - bindAddress = InetAddress.getByAddress(parseIP(bindAddr)); + bindAddress = InetAddress.getByName(bindAddr); } - String hostName = bindAddress.getCanonicalHostName(); + + 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_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8); + getSupportedVersions(port, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, serverConfig); + final NetworkTransportConfiguration settings = - new ServerNetworkTransportConfiguration(serverConfig, port, bindAddress.getHostName(), Transport.TCP); + new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance(); final MultiVersionProtocolEngineFactory protocolEngineFactory = - new MultiVersionProtocolEngineFactory(hostName, supported); + new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply); transport.accept(settings, protocolEngineFactory, null); - ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, port), + + ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress, new QpidAcceptor(transport,"TCP")); CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port)); } @@ -220,22 +242,25 @@ public class Broker { final String keystorePath = serverConfig.getConnectorKeyStorePath(); final String keystorePassword = serverConfig.getConnectorKeyStorePassword(); - final String certType = serverConfig.getConnectorCertType(); - final SSLContext sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, certType); + final String keyManagerFactoryAlgorithm = serverConfig.getConnectorKeyManagerFactoryAlgorithm(); + final SSLContext sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keyManagerFactoryAlgorithm); for(int sslPort : sslPorts) { + final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, sslPort); + final Set<AmqpProtocolVersion> supported = - getSupportedVersions(sslPort, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8); + getSupportedVersions(sslPort, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, serverConfig); final NetworkTransportConfiguration settings = - new ServerNetworkTransportConfiguration(serverConfig, sslPort, bindAddress.getHostName(), Transport.TCP); + new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance(); final MultiVersionProtocolEngineFactory protocolEngineFactory = - new MultiVersionProtocolEngineFactory(hostName, supported); + new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply); transport.accept(settings, protocolEngineFactory, sslContext); - ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, sslPort), + + ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress, new QpidAcceptor(transport,"TCP")); CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort)); } @@ -252,23 +277,24 @@ public class Broker private static Set<AmqpProtocolVersion> getSupportedVersions(final int port, 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> exclude_0_8, + final ServerConfiguration serverConfig) { final EnumSet<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class); - if(exclude_0_10.contains(port)) + if(exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled()) { supported.remove(AmqpProtocolVersion.v0_10); } - if(exclude_0_9_1.contains(port)) + if(exclude_0_9_1.contains(port) || !serverConfig.isAmqp091enabled()) { supported.remove(AmqpProtocolVersion.v0_9_1); } - if(exclude_0_9.contains(port)) + if(exclude_0_9.contains(port) || !serverConfig.isAmqp09enabled()) { supported.remove(AmqpProtocolVersion.v0_9); } - if(exclude_0_8.contains(port)) + if(exclude_0_8.contains(port) || !serverConfig.isAmqp08enabled()) { supported.remove(AmqpProtocolVersion.v0_8); } @@ -354,34 +380,6 @@ public class Broker } } - private byte[] parseIP(String address) throws Exception - { - char[] literalBuffer = address.toCharArray(); - int byteCount = 0; - int currByte = 0; - byte[] ip = new byte[IPV4_ADDRESS_LENGTH]; - for (int i = 0; i < literalBuffer.length; i++) - { - char currChar = literalBuffer[i]; - if ((currChar >= '0') && (currChar <= '9')) - { - currByte = (currByte * 10) + (Character.digit(currChar, 10) & 0xFF); - } - - if (currChar == IPV4_LITERAL_SEPARATOR || (i + 1 == literalBuffer.length)) - { - ip[byteCount++] = (byte) currByte; - currByte = 0; - } - } - - if (byteCount != 4) - { - throw new Exception("Invalid IP address: " + address); - } - return ip; - } - private void configureLogging(File logConfigFile, long logWatchTime) throws InitException, IOException { if (logConfigFile.exists() && logConfigFile.canRead()) @@ -447,7 +445,59 @@ public class Broker blm.register(); } - private java.util.logging.Logger updateLogger(final String logType, String logFileName) throws IOException + private void addShutdownHook() + { + Thread shutdownHookThread = new Thread(new ShutdownService()); + shutdownHookThread.setName("QpidBrokerShutdownHook"); + + Runtime.getRuntime().addShutdownHook(shutdownHookThread); + _shutdownHookThread = shutdownHookThread; + + LOGGER.debug("Added shutdown hook"); + } + + private void removeShutdownHook() + { + Thread shutdownThread = _shutdownHookThread; + + //if there is a shutdown thread and we aren't it, we should remove it + if(shutdownThread != null && !(Thread.currentThread() == shutdownThread)) + { + LOGGER.debug("Removing shutdown hook"); + + _shutdownHookThread = null; + + boolean removed = false; + try + { + removed = Runtime.getRuntime().removeShutdownHook(shutdownThread); + } + catch(IllegalStateException ise) + { + //ignore, means the JVM is already shutting down + } + + if(LOGGER.isDebugEnabled()) + { + LOGGER.debug("Removed shutdown hook: " + removed); + } + } + else + { + LOGGER.debug("Skipping shutdown hook removal as there either isnt one, or we are it."); + } + } + + private class ShutdownService implements Runnable + { + public void run() + { + LOGGER.debug("Shutdown hook running"); + Broker.this.shutdown(); + } + } + + private java.util.logging.Logger updateLogger(final String logType, String logFileName) throws IOException { java.util.logging.Logger logger = java.util.logging.Logger.getLogger(logType); logger.setLevel(Level.FINE); @@ -479,4 +529,5 @@ public class Broker logger.addHandler(handler); return logger; } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java index 3defd8260c..a6b1809d3e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -20,23 +20,28 @@ */ 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; -import org.osgi.framework.BundleContext; - public class BrokerOptions { - /** serialVersionUID */ - private static final long serialVersionUID = 8051825964945442234L; - public static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml"; public static final String QPID_HOME = "QPID_HOME"; + public static final String PORTS = "p"; + public static final String SSL_PORTS = "s"; + public static final String BIND = "b"; + public static final String MANAGEMENT = "m"; + public static final String LOG_CONFIG = "l"; + public static final String WATCH = "w"; + public static final String CONFIG = "c"; + 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>>(); @@ -50,7 +55,6 @@ public class BrokerOptions private Integer _logWatchFrequency = 0; - public void addPort(final int port) { _ports.add(port); @@ -110,7 +114,6 @@ public class BrokerOptions { _jmxPortConnectorServer = jmxPortConnectorServer; } - public String getQpidHome() { return System.getProperty(QPID_HOME); @@ -157,6 +160,7 @@ public class BrokerOptions _logWatchFrequency = logWatchFrequency; } + public BundleContext getBundleContext() { return _bundleContext ; @@ -166,5 +170,4 @@ public class BrokerOptions { _bundleContext = bundleContext; } - }
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java index 9765636c25..0c0b1cf548 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java @@ -20,14 +20,15 @@ */ package org.apache.qpid.server; +import org.apache.log4j.Logger; + +import org.apache.qpid.AMQException; import org.apache.qpid.server.ack.UnacknowledgedMessageMap; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.txn.AutoCommitTransaction; -import org.apache.qpid.AMQException; -import org.apache.log4j.Logger; +import org.apache.qpid.server.txn.ServerTransaction; import java.util.Map; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java index 2bfdd93030..5fcd8a7b52 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -28,6 +28,8 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.log4j.Logger; +import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.server.Broker.InitException; import org.apache.qpid.server.registry.ApplicationRegistry; @@ -124,7 +126,7 @@ public class Main OPTIONS.addOption(OPTION_JMX_PORT_CONNECTOR_SERVER); } - private CommandLine commandLine; + protected CommandLine _commandLine; public static void main(String[] args) { @@ -160,7 +162,7 @@ public class Main { try { - commandLine = new PosixParser().parse(OPTIONS, args); + _commandLine = new PosixParser().parse(OPTIONS, args); return true; } @@ -176,66 +178,93 @@ public class Main protected void execute() throws Exception { - BrokerOptions options = new BrokerOptions(); - String configFile = commandLine.getOptionValue(OPTION_CONFIG_FILE.getOpt()); - if(configFile != null) + if (_commandLine.hasOption(OPTION_HELP.getOpt())) { - options.setConfigFile(configFile); + final HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("Qpid", OPTIONS, true); } - - String logWatchConfig = commandLine.getOptionValue(OPTION_LOG_WATCH.getOpt()); - if(logWatchConfig != null) + else if (_commandLine.hasOption(OPTION_VERSION.getOpt())) { - options.setLogWatchFrequency(Integer.parseInt(logWatchConfig)); - } + final StringBuilder protocol = new StringBuilder("AMQP version(s) [major.minor]: "); + boolean first = true; + for (final ProtocolVersion pv : ProtocolVersion.getSupportedProtocolVersions()) + { + if (first) + { + first = false; + } + else + { + protocol.append(", "); + } - String logConfig = commandLine.getOptionValue(OPTION_LOG_CONFIG_FILE.getOpt()); - if(logConfig != null) - { - options.setLogConfigFile(logConfig); + protocol.append(pv.getMajorVersion()).append('-').append(pv.getMinorVersion()); + } + System.out.println(QpidProperties.getVersionString() + " (" + protocol + ")"); } - - String jmxPortRegistryServer = commandLine.getOptionValue(OPTION_JMX_PORT_REGISTRY_SERVER.getOpt()); - if(jmxPortRegistryServer != null) + else { - options.setJmxPortRegistryServer(Integer.parseInt(jmxPortRegistryServer)); - } + BrokerOptions options = new BrokerOptions(); + String configFile = _commandLine.getOptionValue(OPTION_CONFIG_FILE.getOpt()); + if(configFile != null) + { + options.setConfigFile(configFile); + } - String jmxPortConnectorServer = commandLine.getOptionValue(OPTION_JMX_PORT_CONNECTOR_SERVER.getLongOpt()); - if(jmxPortConnectorServer != null) - { - options.setJmxPortConnectorServer(Integer.parseInt(jmxPortConnectorServer)); - } + String logWatchConfig = _commandLine.getOptionValue(OPTION_LOG_WATCH.getOpt()); + if(logWatchConfig != null) + { + options.setLogWatchFrequency(Integer.parseInt(logWatchConfig)); + } - String bindAddr = commandLine.getOptionValue(OPTION_BIND.getOpt()); - if (bindAddr != null) - { - options.setBind(bindAddr); - } + String logConfig = _commandLine.getOptionValue(OPTION_LOG_CONFIG_FILE.getOpt()); + if(logConfig != null) + { + options.setLogConfigFile(logConfig); + } - String[] portStr = commandLine.getOptionValues(OPTION_PORT.getOpt()); - if(portStr != null) - { - parsePortArray(options, portStr, false); - for(ProtocolExclusion pe : ProtocolExclusion.values()) + String jmxPortRegistryServer = _commandLine.getOptionValue(OPTION_JMX_PORT_REGISTRY_SERVER.getOpt()); + if(jmxPortRegistryServer != null) { - parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe); + options.setJmxPortRegistryServer(Integer.parseInt(jmxPortRegistryServer)); } - } - String[] sslPortStr = commandLine.getOptionValues(OPTION_SSLPORT.getOpt()); - if(sslPortStr != null) - { - parsePortArray(options, sslPortStr, true); - for(ProtocolExclusion pe : ProtocolExclusion.values()) + String jmxPortConnectorServer = _commandLine.getOptionValue(OPTION_JMX_PORT_CONNECTOR_SERVER.getLongOpt()); + if(jmxPortConnectorServer != null) { - parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe); + options.setJmxPortConnectorServer(Integer.parseInt(jmxPortConnectorServer)); } - } - - setExceptionHandler(); - - startBroker(options); + + String bindAddr = _commandLine.getOptionValue(OPTION_BIND.getOpt()); + if (bindAddr != null) + { + options.setBind(bindAddr); + } + + String[] portStr = _commandLine.getOptionValues(OPTION_PORT.getOpt()); + if(portStr != null) + { + parsePortArray(options, portStr, false); + for(ProtocolExclusion pe : ProtocolExclusion.values()) + { + parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe); + } + } + + String[] sslPortStr = _commandLine.getOptionValues(OPTION_SSLPORT.getOpt()); + if(sslPortStr != null) + { + parsePortArray(options, sslPortStr, true); + for(ProtocolExclusion pe : ProtocolExclusion.values()) + { + parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe); + } + } + + setExceptionHandler(); + + startBroker(options); + } } protected void setExceptionHandler() @@ -273,6 +302,7 @@ public class Main { public void uncaughtException(final Thread t, final Throwable e) { + boolean continueOnError = Boolean.getBoolean("qpid.broker.exceptionHandler.continue"); try { System.err.println("########################################################################"); @@ -282,17 +312,20 @@ public class Main System.err.print(" in Thread "); System.err.println(t.getName()); System.err.println("#"); - System.err.println("# Exiting"); + System.err.println(continueOnError ? "# Forced to continue by JVM setting 'qpid.broker.exceptionHandler.continue'" : "# Exiting"); System.err.println("#"); System.err.println("########################################################################"); e.printStackTrace(System.err); Logger logger = Logger.getLogger("org.apache.qpid.server.Main"); - logger.error("Uncaught exception, shutting down.", e); + logger.error("Uncaught exception, " + (continueOnError ? "continuing." : "shutting down."), e); } finally { - Runtime.getRuntime().halt(1); + if (!continueOnError) + { + Runtime.getRuntime().halt(1); + } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java index f4b4932744..842b36cf75 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMap.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.ack; -import java.util.Collection; -import java.util.Set; -import java.util.Map; - import org.apache.qpid.AMQException; import org.apache.qpid.server.queue.QueueEntry; +import java.util.Collection; +import java.util.Set; + public interface UnacknowledgedMessageMap { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java index 6a5d863526..b8b15c8c28 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java @@ -20,14 +20,14 @@ */ package org.apache.qpid.server.ack; +import org.apache.qpid.AMQException; +import org.apache.qpid.server.queue.QueueEntry; + import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import org.apache.qpid.AMQException; -import org.apache.qpid.server.queue.QueueEntry; - public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap { private final Object _lock = new Object(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java index 48f85d9bc9..8e44da095a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java @@ -94,7 +94,7 @@ public class Binding return true; } - if (o == null || !(o instanceof Binding)) + if (!(o instanceof Binding)) { return false; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java index 94ab43c851..fe66a6d341 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java @@ -20,10 +20,6 @@ */ package org.apache.qpid.server.binding; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - import org.apache.qpid.AMQException; import org.apache.qpid.AMQInternalException; import org.apache.qpid.AMQSecurityException; @@ -33,8 +29,6 @@ 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.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.BindingMessages; @@ -43,6 +37,10 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + public class BindingFactory { private final VirtualHost _virtualHost; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java index 5cd064ff42..1ed6b38758 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java @@ -21,9 +21,11 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +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> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java index a8d3cd9ec3..888feeff0c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java @@ -21,9 +21,10 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public final class BridgeConfigType extends ConfigObjectType<BridgeConfigType, BridgeConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java index e1cf87277b..64a59c3f61 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java @@ -21,7 +21,10 @@ package org.apache.qpid.server.configuration; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public final class BrokerConfigType extends ConfigObjectType<BrokerConfigType, BrokerConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java index 4e031f0a84..aff07250f3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.configuration; -import java.util.UUID; 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; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java index 2c492ff6b9..06402fa646 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java @@ -20,17 +20,18 @@ */ package org.apache.qpid.server.configuration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - 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 diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java index 9750b12dea..5631fda37c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java @@ -21,9 +21,10 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public final class ConnectionConfigType extends ConfigObjectType<ConnectionConfigType, ConnectionConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java index 2095301ad6..c7744117c4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java @@ -21,9 +21,11 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +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> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java index 0b3a9076dd..2c37a94db0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java @@ -21,11 +21,6 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.Map; - - public interface LinkConfig extends ConfiguredObject<LinkConfigType, LinkConfig> { VirtualHostConfig getVirtualHost(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java index 4dc46b70c9..ea4f723dda 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java @@ -21,9 +21,10 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java index be34c8d63d..1ef5edeb51 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.configuration; -import java.util.Map; - import org.apache.qpid.AMQException; +import java.util.Map; + public interface QueueConfig extends ConfiguredObject<QueueConfigType, QueueConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java index a794ed9747..f958ef5350 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java @@ -21,9 +21,11 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +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> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java index 759907d4bd..a9e45f7415 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java @@ -20,13 +20,14 @@ */ package org.apache.qpid.server.configuration; -import java.util.List; - 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 java.util.List; + public class QueueConfiguration extends ConfigurationPlugin { private String _name; @@ -211,7 +212,7 @@ public class QueueConfiguration extends ConfigurationPlugin public void validateConfiguration() throws ConfigurationException { - if (_configuration.isEmpty()) + if (getConfig().isEmpty()) { throw new ConfigurationException("Queue section cannot be empty."); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java index d3b89649c7..5d0546f6a7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java @@ -20,17 +20,6 @@ package org.apache.qpid.server.configuration; -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; - -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 org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; @@ -39,14 +28,29 @@ 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; + +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; + public class ServerConfiguration extends ConfigurationPlugin { protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class); @@ -84,10 +88,14 @@ public class ServerConfiguration extends ConfigurationPlugin public static final String MGMT_JMXPORT_CONNECTORSERVER = "management.jmxport.connectorServer"; public static final String STATUS_UPDATES = "status-updates"; public static final String ADVANCED_LOCALE = "advanced.locale"; + 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"; { envVarMap.put("QPID_PORT", "connector.port"); - envVarMap.put("QPID_ENABLEDIRECTBUFFERS", "advanced.enableDirectBuffers"); envVarMap.put("QPID_SSLPORT", "connector.ssl.port"); envVarMap.put("QPID_JMXPORT_REGISTRYSERVER", MGMT_JMXPORT_REGISTRYSERVER); envVarMap.put("QPID_JMXPORT_CONNECTORSERVER", MGMT_JMXPORT_CONNECTORSERVER); @@ -108,7 +116,6 @@ public class ServerConfiguration extends ConfigurationPlugin envVarMap.put("QPID_SOCKETRECEIVEBUFFER", "connector.socketReceiveBuffer"); envVarMap.put("QPID_SOCKETWRITEBUFFER", "connector.socketWriteBuffer"); envVarMap.put("QPID_TCPNODELAY", "connector.tcpNoDelay"); - envVarMap.put("QPID_ENABLEPOOLEDALLOCATOR", "advanced.enablePooledAllocator"); envVarMap.put("QPID_STATUS-UPDATES", "status-updates"); } @@ -177,7 +184,7 @@ public class ServerConfiguration extends ConfigurationPlugin */ public ServerConfiguration(Configuration conf) { - _configuration = conf; + setConfig(conf); } /** @@ -197,8 +204,8 @@ public class ServerConfiguration extends ConfigurationPlugin */ public void initialise() throws ConfigurationException { - setConfiguration("", _configuration); - setupVirtualHosts(_configuration); + setConfiguration("", getConfig()); + setupVirtualHosts(getConfig()); } public String[] getElementsProcessed() @@ -256,6 +263,13 @@ public class ServerConfiguration extends ConfigurationPlugin + (_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)); + } } /* @@ -303,7 +317,7 @@ public class ServerConfiguration extends ConfigurationPlugin // save the default virtualhost name String defaultVirtualHost = vhostConfiguration.getString("default"); - _configuration.setProperty("virtualhosts.default", defaultVirtualHost); + getConfig().setProperty("virtualhosts.default", defaultVirtualHost); } } @@ -472,7 +486,7 @@ public class ServerConfiguration extends ConfigurationPlugin { VirtualHost vhost = vhostRegistry.getVirtualHost(hostName); Configuration vhostConfig = newVhosts.subset("virtualhost." + hostName); - vhost.getConfiguration().setConfiguration("virtualhosts.virtualhost", vhostConfig); // XXX + vhost.getConfiguration().setConfiguration("virtualhosts.virtualhost", vhostConfig); vhost.getSecurityManager().configureGlobalPlugins(this); vhost.getSecurityManager().configureHostPlugins(vhost.getConfiguration()); } @@ -608,11 +622,6 @@ public class ServerConfiguration extends ConfigurationPlugin return getDoubleValue("heartbeat.timeoutFactor", 2.0); } - public int getDeliveryPoolSize() - { - return getIntValue("delivery.poolsize"); - } - public long getMaximumMessageAge() { return getLongValue("maximumMessageAge"); @@ -698,11 +707,6 @@ public class ServerConfiguration extends ConfigurationPlugin return getBooleanValue("connector.tcpNoDelay", true); } - public boolean getEnableExecutorPool() - { - return getBooleanValue("advanced.filterchain[@enableExecutorPool]"); - } - public boolean getEnableSSL() { return getBooleanValue("connector.ssl.enabled"); @@ -730,9 +734,12 @@ public class ServerConfiguration extends ConfigurationPlugin return getStringValue("connector.ssl.keyStorePassword", fallback); } - public String getConnectorCertType() + public String getConnectorKeyManagerFactoryAlgorithm() { - return getStringValue("connector.ssl.certType", "SunX509"); + 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 getDefaultVirtualHost() @@ -836,4 +843,33 @@ public class ServerConfiguration extends ConfigurationPlugin return getConfig().getString("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); } + 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); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java index 81dfcb4465..f6fe47b996 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java @@ -19,22 +19,21 @@ */ 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 int _port; - private final String _host; private final String _transport; + private InetSocketAddress _address; public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig, - final int port, final String host, + final InetSocketAddress address, final String transport) { _serverConfig = serverConfig; - _port = port; - _host = host; + _address = address; _transport = transport; } @@ -55,12 +54,12 @@ public class ServerNetworkTransportConfiguration implements NetworkTransportConf public Integer getPort() { - return _port; + return _address.getPort(); } public String getHost() { - return _host; + return _address.getHostName(); } public String getTransport() @@ -72,4 +71,9 @@ public class ServerNetworkTransportConfiguration implements NetworkTransportConf { return _serverConfig.getConnectorProcessors(); } + + public InetSocketAddress getAddress() + { + return _address; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java index 97cf275575..1685cfab60 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java @@ -21,9 +21,10 @@ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public final class SessionConfigType extends ConfigObjectType<SessionConfigType, SessionConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java index 99d3273b55..7b7848dd87 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java @@ -22,7 +22,11 @@ package org.apache.qpid.server.configuration; -import java.util.*; +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> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java index 09ebb07105..98109ce1e8 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java @@ -21,11 +21,11 @@ package org.apache.qpid.server.configuration; -import java.util.UUID; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; 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 { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java index f5aabd2345..d7c36da4e0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java @@ -21,7 +21,11 @@ package org.apache.qpid.server.configuration; -import java.util.*; +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> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java index d5420d9718..10e40151b0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java @@ -22,13 +22,14 @@ 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() { - _configuration = new PropertiesConfiguration(); + setConfig(new PropertiesConfiguration()); } @Override @@ -50,7 +51,7 @@ public class TopicConfig extends ConfigurationPlugin public void validateConfiguration() throws ConfigurationException { - if (_configuration.isEmpty()) + if (getConfig().isEmpty()) { throw new ConfigurationException("Topic section cannot be empty."); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java index 8716fed8c1..feafd3de1d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java @@ -22,6 +22,7 @@ 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; @@ -56,8 +57,8 @@ public class TopicConfiguration extends ConfigurationPlugin implements ExchangeC } } - Map<String, TopicConfig> _topics = new HashMap<String, TopicConfig>(); - Map<String, Map<String, TopicConfig>> _subscriptions = new HashMap<String, Map<String, TopicConfig>>(); + 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() { @@ -67,17 +68,17 @@ public class TopicConfiguration extends ConfigurationPlugin implements ExchangeC @Override public void validateConfiguration() throws ConfigurationException { - if (_configuration.isEmpty()) + if (getConfig().isEmpty()) { throw new ConfigurationException("Topics section cannot be empty."); } - int topics = _configuration.getList("topic.name").size() + - _configuration.getList("topic.subscriptionName").size(); + int topics = getConfig().getList("topic.name").size() + + getConfig().getList("topic.subscriptionName").size(); for (int index = 0; index < topics; index++) { - Configuration topicSubset = _configuration.subset("topic(" + index + ")"); + Configuration topicSubset = getConfig().subset("topic(" + index + ")"); // This will occur when we have a subscriptionName that is bound to a // topic. @@ -90,8 +91,8 @@ public class TopicConfiguration extends ConfigurationPlugin implements ExchangeC topic.setConfiguration(VIRTUALHOSTS_VIRTUALHOST_TOPICS + ".topic", topicSubset ); - String name = _configuration.getString("topic(" + index + ").name"); - String subscriptionName = _configuration.getString("topic(" + index + ").subscriptionName"); + String name = getConfig().getString("topic(" + index + ").name"); + String subscriptionName = getConfig().getString("topic(" + index + ").subscriptionName"); // Record config if subscriptionName is there if (subscriptionName != null) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java index 96682335bf..16e08e3934 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java @@ -21,7 +21,10 @@ package org.apache.qpid.server.configuration; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; public class VirtualHostConfigType extends ConfigObjectType<VirtualHostConfigType, VirtualHostConfig> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java index c4e4f701a8..558311fc46 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java @@ -20,17 +20,11 @@ */ package org.apache.qpid.server.configuration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - 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; @@ -39,11 +33,18 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.MemoryMessageStore; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + public class VirtualHostConfiguration extends ConfigurationPlugin { - private String _name; - private Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>(); - private Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>(); + private final String _name; + private final Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>(); + private final Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>(); public VirtualHostConfiguration(String name, Configuration config) throws ConfigurationException { @@ -75,7 +76,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin { CompositeConfiguration mungedConf = new CompositeConfiguration(); mungedConf.addConfiguration(config.subset("exchanges.exchange(" + count++ + ")")); - mungedConf.addConfiguration(_configuration.subset("exchanges")); + mungedConf.addConfiguration(getConfig().subset("exchanges")); String exchName = (String) i.next(); _exchanges.put(exchName, new ExchangeConfiguration(exchName, mungedConf)); } @@ -91,11 +92,6 @@ public class VirtualHostConfiguration extends ConfigurationPlugin return getLongValue("housekeeping.checkPeriod", ApplicationRegistry.getInstance().getConfiguration().getHousekeepingCheckPeriod()); } - public String getAuthenticationDatabase() - { - return getStringValue("security.authentication.name"); - } - public List getCustomExchanges() { return getListValue("custom-exchanges.class-name"); @@ -103,7 +99,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin public Configuration getStoreConfiguration() { - return _configuration.subset("store"); + return getConfig().subset("store"); } public String getMessageStoreClass() @@ -113,7 +109,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin public void setMessageStoreClass(String storeClass) { - _configuration.setProperty("store.class", storeClass); + getConfig().setProperty("store.class", storeClass); } public List getExchanges() @@ -252,16 +248,6 @@ public class VirtualHostConfiguration extends ConfigurationPlugin return queueConfig; } - public long getMemoryUsageMaximum() - { - return getLongValue("queues.maximumMemoryUsage"); - } - - public long getMemoryUsageMinimum() - { - return getLongValue("queues.minimumMemoryUsage"); - } - public int getMaximumMessageAge() { return getIntValue("queues.maximumMessageAge"); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java index cc402d5b4a..f0ca5dc139 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.configuration.management; -import javax.management.NotCompliantMBeanException; - -import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.management.common.mbeans.ConfigurationManagement; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.registry.ApplicationRegistry; +import javax.management.NotCompliantMBeanException; + public class ConfigurationManagementMBean extends AMQManagedObject implements ConfigurationManagement { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java index b4f82649b0..d08e3bc806 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java @@ -22,6 +22,7 @@ import org.apache.commons.configuration.Configuration; 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; @@ -42,7 +43,7 @@ public abstract class ConfigurationPlugin private Map<String, ConfigurationPlugin> _pluginConfiguration = new HashMap<String, ConfigurationPlugin>(); - protected Configuration _configuration; + private Configuration _config; /** * The Elements that this Plugin can process. @@ -65,7 +66,7 @@ public abstract class ConfigurationPlugin public Configuration getConfig() { - return _configuration; + return _config; } public <C extends ConfigurationPlugin> C getConfiguration(String plugin) @@ -81,7 +82,7 @@ public abstract class ConfigurationPlugin */ public void setConfiguration(String path, Configuration configuration) throws ConfigurationException { - _configuration = configuration; + _config = configuration; // Extract a list of elements for processing Iterator<?> keys = configuration.getKeys(); @@ -215,7 +216,7 @@ public abstract class ConfigurationPlugin protected boolean hasConfiguration() { - return _configuration != null; + return _config != null; } /// Getters @@ -227,7 +228,7 @@ public abstract class ConfigurationPlugin protected double getDoubleValue(String property, double defaultValue) { - return _configuration.getDouble(property, defaultValue); + return _config.getDouble(property, defaultValue); } protected long getLongValue(String property) @@ -237,7 +238,7 @@ public abstract class ConfigurationPlugin protected long getLongValue(String property, long defaultValue) { - return _configuration.getLong(property, defaultValue); + return _config.getLong(property, defaultValue); } protected int getIntValue(String property) @@ -247,7 +248,7 @@ public abstract class ConfigurationPlugin protected int getIntValue(String property, int defaultValue) { - return _configuration.getInt(property, defaultValue); + return _config.getInt(property, defaultValue); } protected String getStringValue(String property) @@ -257,7 +258,7 @@ public abstract class ConfigurationPlugin protected String getStringValue(String property, String defaultValue) { - return _configuration.getString(property, defaultValue); + return _config.getString(property, defaultValue); } protected boolean getBooleanValue(String property) @@ -267,7 +268,7 @@ public abstract class ConfigurationPlugin protected boolean getBooleanValue(String property, boolean defaultValue) { - return _configuration.getBoolean(property, defaultValue); + return _config.getBoolean(property, defaultValue); } protected List getListValue(String property) @@ -277,14 +278,14 @@ public abstract class ConfigurationPlugin protected List getListValue(String property, List defaultValue) { - return _configuration.getList(property, defaultValue); + return _config.getList(property, defaultValue); } /// Validation Helpers protected boolean contains(String property) { - return _configuration.getProperty(property) != null; + return _config.getProperty(property) != null; } /** @@ -323,7 +324,7 @@ public abstract class ConfigurationPlugin throw new ConfigurationException(this.getClass().getSimpleName() + ": unable to configure invalid " + property + ":" + - _configuration.getString(property), + _config.getString(property), last); } } @@ -332,7 +333,7 @@ public abstract class ConfigurationPlugin { try { - _configuration.getLong(property); + _config.getLong(property); return true; } catch (NoSuchElementException e) @@ -345,7 +346,7 @@ public abstract class ConfigurationPlugin { try { - long value = _configuration.getLong(property); + long value = _config.getLong(property); return value > 0; } catch (NoSuchElementException e) @@ -359,7 +360,7 @@ public abstract class ConfigurationPlugin { try { - _configuration.getInt(property); + _config.getInt(property); return true; } catch (NoSuchElementException e) @@ -372,7 +373,7 @@ public abstract class ConfigurationPlugin { try { - _configuration.getBoolean(property); + _config.getBoolean(property); return true; } catch (NoSuchElementException e) @@ -453,7 +454,7 @@ public abstract class ConfigurationPlugin protected void mergeConfiguration(ConfigurationPlugin configuration) { - _configuration = configuration.getConfig(); + _config = configuration.getConfig(); } public String toString() @@ -478,6 +479,10 @@ public abstract class ConfigurationPlugin return super.toString(); } + protected void setConfig(Configuration config) + { + _config = config; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java index 02560b296e..fa41f3ef06 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.configuration.plugins; -import java.util.List; - import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; +import java.util.List; + public interface ConfigurationPluginFactory { /** diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java index 7a2632d923..a90b1d514f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java @@ -22,9 +22,6 @@ package org.apache.qpid.server.configuration.plugins; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.ConversionException; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import java.util.Arrays; import java.util.List; @@ -48,7 +45,7 @@ public class SlowConsumerDetectionConfiguration extends ConfigurationPlugin } //Set Default time unit to seconds - TimeUnit _timeUnit = TimeUnit.SECONDS; + private TimeUnit _timeUnit = TimeUnit.SECONDS; public String[] getElementsProcessed() { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java index ca8dec851a..a9026c6164 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java @@ -22,8 +22,6 @@ package org.apache.qpid.server.configuration.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 java.util.Arrays; import java.util.List; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java index 6f8020fc54..cb3bb5a77f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java @@ -22,8 +22,7 @@ package org.apache.qpid.server.configuration.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.plugins.PluginManager; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java index 1c01ce465d..9159489299 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java @@ -20,18 +20,18 @@ */ package org.apache.qpid.server.connection; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.common.Closeable; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.protocol.AMQConnectionModel; -import org.apache.qpid.server.protocol.AMQProtocolEngine; import org.apache.qpid.transport.TransportException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + public class ConnectionRegistry implements IConnectionRegistry, Closeable { private List<AMQConnectionModel> _registry = new CopyOnWriteArrayList<AMQConnectionModel>(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java index b4f5bffa57..89582e5748 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java @@ -20,12 +20,12 @@ */ package org.apache.qpid.server.connection; -import java.util.List; - import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.protocol.AMQConnectionModel; +import java.util.List; + public interface IConnectionRegistry { public void initialise(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java index 5ff90b3499..cae07046fa 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java @@ -41,7 +41,6 @@ import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; import javax.management.JMException; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -62,20 +61,20 @@ public abstract class AbstractExchange implements Exchange, Managable private Exchange _alternateExchange; - protected boolean _durable; - protected int _ticket; + private boolean _durable; + private int _ticket; private VirtualHost _virtualHost; private final List<Exchange.Task> _closeTaskList = new CopyOnWriteArrayList<Exchange.Task>(); - protected AbstractExchangeMBean _exchangeMbean; + private AbstractExchangeMBean _exchangeMbean; /** * Whether the exchange is automatically deleted once all queues have detached from it */ - protected boolean _autoDelete; + private boolean _autoDelete; //The logSubject for ths exchange private LogSubject _logSubject; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java index 0f1b709475..034331abd9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java @@ -20,29 +20,31 @@ */ package org.apache.qpid.server.exchange; -import java.util.Collections; -import java.util.Map; - import org.apache.qpid.AMQException; -import org.apache.qpid.AMQSecurityException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.management.common.mbeans.ManagedExchange; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.ManagementActor; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.management.ManagedObjectRegistry; +import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.ManagementActor; -import org.apache.qpid.management.common.mbeans.ManagedExchange; -import org.apache.qpid.framing.AMQShortString; -import javax.management.openmbean.*; +import javax.management.JMException; import javax.management.MBeanException; +import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; -import javax.management.MalformedObjectNameException; -import javax.management.JMException; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularType; +import java.util.Collections; + /** * Abstract MBean class. This has some of the methods implemented from @@ -52,9 +54,9 @@ import javax.management.JMException; public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends AMQManagedObject implements ManagedExchange { // open mbean data types for representing exchange bindings - protected OpenType[] _bindingItemTypes; - protected CompositeType _bindingDataType; - protected TabularType _bindinglistDataType; + private OpenType[] _bindingItemTypes; + private CompositeType _bindingDataType; + private TabularType _bindinglistDataType; private T _exchange; @@ -105,17 +107,17 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends public Integer getTicketNo() { - return _exchange._ticket; + return _exchange.getTicket(); } public boolean isDurable() { - return _exchange._durable; + return _exchange.isDurable(); } public boolean isAutoDelete() { - return _exchange._autoDelete; + return _exchange.isAutoDelete(); } // Added exchangetype in the object name lets maangement apps to do any customization required @@ -140,7 +142,7 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends throw new JMException("Queue \"" + queueName + "\" is not registered with the virtualhost."); } - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { vhost.getBindingFactory().addBinding(binding,queue,getExchange(),null); @@ -156,7 +158,7 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends /** * Removes a queue binding from the exchange. * - * @see BindingFactory#removeBinding(String, AMQQueue, Exchange, Map) + * @see org.apache.qpid.server.binding.BindingFactory#removeBinding(String, AMQQueue, Exchange, java.util.Map) */ public void removeBinding(String queueName, String binding) throws JMException { @@ -167,7 +169,7 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends throw new JMException("Queue \"" + queueName + "\" is not registered with the virtualhost."); } - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { vhost.getBindingFactory().removeBinding(binding, queue, _exchange, Collections.<String, Object>emptyMap()); @@ -179,4 +181,35 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends } CurrentActor.remove(); } + + + protected OpenType[] getBindingItemTypes() + { + return _bindingItemTypes; + } + + protected void setBindingItemTypes(OpenType[] bindingItemTypes) + { + _bindingItemTypes = bindingItemTypes; + } + + protected CompositeType getBindingDataType() + { + return _bindingDataType; + } + + protected void setBindingDataType(CompositeType bindingDataType) + { + _bindingDataType = bindingDataType; + } + + protected TabularType getBindinglistDataType() + { + return _bindinglistDataType; + } + + protected void setBindinglistDataType(TabularType bindinglistDataType) + { + _bindinglistDataType = bindinglistDataType; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java index 090c0426cf..153419de1b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java @@ -20,23 +20,22 @@ */ package org.apache.qpid.server.exchange; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - import org.apache.log4j.Logger; -import org.apache.qpid.AMQConnectionException; + import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.AMQUnknownExchangeType; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.qmf.ManagementExchange; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + public class DefaultExchangeFactory implements ExchangeFactory { private static final Logger _logger = Logger.getLogger(DefaultExchangeFactory.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java index 8d2dee5aaa..a5fa9f014e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java @@ -20,20 +20,20 @@ */ package org.apache.qpid.server.exchange; -import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; 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.queue.IncomingMessage; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Collection; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + public class DefaultExchangeRegistry implements ExchangeRegistry { private static final Logger _log = Logger.getLogger(DefaultExchangeRegistry.class); @@ -153,24 +153,4 @@ public class DefaultExchangeRegistry implements ExchangeRegistry } } - - /** - * Routes content through exchanges, delivering it to 1 or more queues. - * @param payload - * @throws AMQException if something goes wrong delivering data - */ - public void routeContent(IncomingMessage payload) throws AMQException - { - final AMQShortString exchange = payload.getExchange(); - final Exchange exch = getExchange(exchange); - // there is a small window of opportunity for the exchange to be deleted in between - // the BasicPublish being received (where the exchange is validated) and the final - // content body being received (which triggers this method) - // TODO: check where the exchange is validated - if (exch == null) - { - throw new AMQException("Exchange '" + exchange + "' does not exist"); - } - payload.enqueue(exch.route(payload)); - } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java index 94fc44d9c7..0bfaf7035d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeMBean.java @@ -20,16 +20,20 @@ */ package org.apache.qpid.server.exchange; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.server.binding.Binding; import javax.management.JMException; -import javax.management.openmbean.*; -import java.util.List; -import java.util.Map; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * MBean class implementing the management interfaces. @@ -47,7 +51,7 @@ final class DirectExchangeMBean extends AbstractExchangeMBean<DirectExchange> public TabularData bindings() throws OpenDataException { - TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType); + TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType()); Map<String, List<String>> bindingMap = new HashMap<String, List<String>>(); @@ -67,7 +71,7 @@ final class DirectExchangeMBean extends AbstractExchangeMBean<DirectExchange> for(Map.Entry<String, List<String>> entry : bindingMap.entrySet()) { Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[0])}; - CompositeData bindingData = new CompositeDataSupport(_bindingDataType, + CompositeData bindingData = new CompositeDataSupport(getBindingDataType(), COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), bindingItemValues); bindingList.put(bindingData); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java index 29c354feae..0bcfc3a3da 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java @@ -25,18 +25,17 @@ import org.apache.qpid.AMQInternalException; 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.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ExchangeConfig; import javax.management.JMException; -import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; public interface Exchange extends ExchangeReferrer, ExchangeConfig { @@ -113,6 +112,8 @@ public interface Exchange extends ExchangeReferrer, ExchangeConfig boolean isBound(String bindingKey, AMQQueue queue); + public boolean isBound(String bindingKey, Map<String,Object> arguments, AMQQueue queue); + boolean isBound(String bindingKey); void addCloseTask(Task task); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java index 92795487e4..577da79028 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java @@ -20,12 +20,12 @@ */ package org.apache.qpid.server.exchange; -import java.util.Collection; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import java.util.Collection; + public interface ExchangeFactory { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java index e34ef29d9b..18eb37e037 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java @@ -26,7 +26,7 @@ import org.apache.qpid.framing.AMQShortString; import java.util.Collection; -public interface ExchangeRegistry extends MessageRouter +public interface ExchangeRegistry { void registerExchange(Exchange exchange) throws AMQException; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java index 0b55caa2f1..ce339c4e29 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.exchange; -import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.virtualhost.VirtualHost; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java index 2c85b7f787..61e23c896c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeMBean.java @@ -20,12 +20,16 @@ */ package org.apache.qpid.server.exchange; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.server.binding.Binding; import javax.management.JMException; -import javax.management.openmbean.*; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; import java.util.ArrayList; /** @@ -46,7 +50,7 @@ final class FanoutExchangeMBean extends AbstractExchangeMBean<FanoutExchange> public TabularData bindings() throws OpenDataException { - TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType); + TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType()); ArrayList<String> queueNames = new ArrayList<String>(); @@ -58,7 +62,7 @@ final class FanoutExchangeMBean extends AbstractExchangeMBean<FanoutExchange> } Object[] bindingItemValues = {BINDING_KEY_SUBSTITUTE, queueNames.toArray(new String[0])}; - CompositeData bindingData = new CompositeDataSupport(_bindingDataType, + CompositeData bindingData = new CompositeDataSupport(getBindingDataType(), COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), bindingItemValues); bindingList.put(bindingData); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java index f58a6513a9..b6f5f973f4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersBinding.java @@ -20,17 +20,18 @@ */ package org.apache.qpid.server.exchange; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - import org.apache.log4j.Logger; + import org.apache.qpid.framing.AMQTypedValue; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.AMQMessageHeader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + /** * Defines binding and matching based on a set of headers. */ @@ -38,7 +39,7 @@ class HeadersBinding { private static final Logger _logger = Logger.getLogger(HeadersBinding.class); - private final FieldTable _mappings; + private final Map<String,Object> _mappings; private final Binding _binding; private final Set<String> required = new HashSet<String>(); private final Map<String,Object> matches = new HashMap<String,Object>(); @@ -57,7 +58,7 @@ class HeadersBinding _binding = binding; if(_binding !=null) { - _mappings = FieldTable.convertToFieldTable(_binding.getArguments()); + _mappings = _binding.getArguments(); initMappings(); } else @@ -68,37 +69,23 @@ class HeadersBinding private void initMappings() { - _mappings.processOverElements(new FieldTable.FieldTableElementProcessor() + for(Map.Entry<String, Object> entry : _mappings.entrySet()) { - - public boolean processElement(String propertyName, AMQTypedValue value) + String propertyName = entry.getKey(); + Object value = entry.getValue(); + if (isSpecial(propertyName)) { - if (isSpecial(propertyName)) - { - processSpecial(propertyName, value.getValue()); - } - else if (value.getValue() == null || value.getValue().equals("")) - { - required.add(propertyName); - } - else - { - matches.put(propertyName,value.getValue()); - } - - return true; + processSpecial(propertyName, value); } - - public Object getResult() + else if (value == null || value.equals("")) { - return null; + required.add(propertyName); } - }); - } - - protected FieldTable getMappings() - { - return _mappings; + else + { + matches.put(propertyName,value); + } + } } public Binding getBinding() @@ -206,8 +193,14 @@ class HeadersBinding { if(value instanceof String) { - if("any".equalsIgnoreCase((String) value)) return true; - if("all".equalsIgnoreCase((String) value)) return false; + if("any".equalsIgnoreCase((String) value)) + { + return true; + } + if("all".equalsIgnoreCase((String) value)) + { + return false; + } } _logger.warn("Ignoring unrecognised match type: " + value); return false;//default to all diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java index f9cbfeb78b..295a7191e7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java @@ -21,23 +21,24 @@ 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.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.AMQMessageHeader; -import org.apache.qpid.server.binding.Binding; import javax.management.JMException; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; /** @@ -145,6 +146,33 @@ public class HeadersExchange extends AbstractExchange return new ArrayList<BaseQueue>(queues); } + + public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue) + { + CopyOnWriteArraySet<Binding> bindings; + if(bindingKey == null) + { + bindings = new CopyOnWriteArraySet<Binding>(getBindings()); + } + else + { + bindings = _bindingsByKey.get(bindingKey); + } + + if(bindings != null) + { + for(Binding binding : bindings) + { + if(queue == null || binding.getQueue().equals(queue)) + { + return arguments == null ? binding.getArguments() == null : binding.getArguments().equals(arguments); + } + } + } + + return false; + } + public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) { //fixme isBound here should take the arguements in to consideration. @@ -250,10 +278,11 @@ public class HeadersExchange extends AbstractExchange { bindings.remove(binding); } - + + boolean removedBinding = _bindingHeaderMatchers.remove(new HeadersBinding(binding)); if(_logger.isDebugEnabled()) { - _logger.debug("Removing Binding: " + _bindingHeaderMatchers.remove(new HeadersBinding(binding))); + _logger.debug("Removing Binding: " + removedBinding); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java index caed8f4b94..395c6c8a91 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeMBean.java @@ -22,8 +22,8 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.ManagementActor; @@ -32,11 +32,19 @@ import org.apache.qpid.server.virtualhost.VirtualHost; import javax.management.JMException; import javax.management.MBeanException; -import javax.management.openmbean.*; - +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.ArrayList; import java.util.Map; /** @@ -60,20 +68,20 @@ final class HeadersExchangeMBean extends AbstractExchangeMBean<HeadersExchange> protected void init() throws OpenDataException { - _bindingItemTypes = new OpenType[3]; - _bindingItemTypes[0] = SimpleType.INTEGER; - _bindingItemTypes[1] = SimpleType.STRING; - _bindingItemTypes[2] = new ArrayType(1, SimpleType.STRING); - _bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings", - HEADERS_COMPOSITE_ITEM_NAMES.toArray(new String[HEADERS_COMPOSITE_ITEM_NAMES.size()]), - HEADERS_COMPOSITE_ITEM_DESC.toArray(new String[HEADERS_COMPOSITE_ITEM_DESC.size()]), _bindingItemTypes); - _bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(), - _bindingDataType, HEADERS_TABULAR_UNIQUE_INDEX.toArray(new String[HEADERS_TABULAR_UNIQUE_INDEX.size()])); + setBindingItemTypes(new OpenType[3]); + getBindingItemTypes()[0] = SimpleType.INTEGER; + getBindingItemTypes()[1] = SimpleType.STRING; + getBindingItemTypes()[2] = new ArrayType(1, SimpleType.STRING); + setBindingDataType(new CompositeType("Exchange Binding", "Queue name and header bindings", + HEADERS_COMPOSITE_ITEM_NAMES.toArray(new String[HEADERS_COMPOSITE_ITEM_NAMES.size()]), + HEADERS_COMPOSITE_ITEM_DESC.toArray(new String[HEADERS_COMPOSITE_ITEM_DESC.size()]), getBindingItemTypes())); + setBindinglistDataType(new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(), + getBindingDataType(), HEADERS_TABULAR_UNIQUE_INDEX.toArray(new String[HEADERS_TABULAR_UNIQUE_INDEX.size()]))); } public TabularData bindings() throws OpenDataException { - TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType); + TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType()); int count = 1; for (Binding binding : getExchange().getBindings()) { @@ -95,7 +103,7 @@ final class HeadersExchangeMBean extends AbstractExchangeMBean<HeadersExchange> Object[] bindingItemValues = {count++, queueName, mappingList.toArray(new String[0])}; - CompositeData bindingData = new CompositeDataSupport(_bindingDataType, + CompositeData bindingData = new CompositeDataSupport(getBindingDataType(), HEADERS_COMPOSITE_ITEM_NAMES.toArray(new String[HEADERS_COMPOSITE_ITEM_NAMES.size()]), bindingItemValues); bindingList.put(bindingData); } @@ -113,7 +121,7 @@ final class HeadersExchangeMBean extends AbstractExchangeMBean<HeadersExchange> throw new JMException("Queue \"" + queueName + "\" is not registered with the virtualhost."); } - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); final Map<String,Object> arguments = new HashMap<String, Object>(); final String[] bindings = binding.split(","); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java index 3a8a86e654..27166e4384 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java @@ -20,29 +20,39 @@ */ package org.apache.qpid.server.exchange; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +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; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.exchange.topic.*; +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.filter.JMSSelectorFilter; +import org.apache.qpid.server.filter.MessageFilter; import org.apache.qpid.server.message.InboundMessage; - -import javax.management.JMException; -import java.sql.Array; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -import java.lang.ref.WeakReference; +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 { @@ -113,24 +123,26 @@ public class TopicExchange extends AbstractExchange FieldTable oldArgs = _bindings.get(binding); TopicExchangeResult result = _topicExchangeResults.get(routingKey); - if(argumentsContainSelector(args)) + if(argumentsContainFilter(args)) { - if(argumentsContainSelector(oldArgs)) + if(argumentsContainFilter(oldArgs)) { - result.replaceQueueFilter(queue,createSelectorFilter(oldArgs), createSelectorFilter(args)); + result.replaceQueueFilter(queue, + createMessageFilter(oldArgs, queue), + createMessageFilter(args, queue)); } else { - result.addFilteredQueue(queue,createSelectorFilter(args)); + result.addFilteredQueue(queue, createMessageFilter(args, queue)); result.removeUnfilteredQueue(queue); } } else { - if(argumentsContainSelector(oldArgs)) + if(argumentsContainFilter(oldArgs)) { result.addUnfilteredQueue(queue); - result.removeFilteredQueue(queue, createSelectorFilter(oldArgs)); + result.removeFilteredQueue(queue, createMessageFilter(oldArgs, queue)); } else { @@ -149,9 +161,9 @@ public class TopicExchange extends AbstractExchange if(result == null) { result = new TopicExchangeResult(); - if(argumentsContainSelector(args)) + if(argumentsContainFilter(args)) { - result.addFilteredQueue(queue, createSelectorFilter(args)); + result.addFilteredQueue(queue, createMessageFilter(args, queue)); } else { @@ -162,9 +174,9 @@ public class TopicExchange extends AbstractExchange } else { - if(argumentsContainSelector(args)) + if(argumentsContainFilter(args)) { - result.addFilteredQueue(queue, createSelectorFilter(args)); + result.addFilteredQueue(queue, createMessageFilter(args, queue)); } else { @@ -178,26 +190,74 @@ public class TopicExchange extends AbstractExchange } - private JMSSelectorFilter createSelectorFilter(final FieldTable args) throws AMQInvalidArgumentException + private MessageFilter createMessageFilter(final FieldTable args, AMQQueue queue) throws AMQInvalidArgumentException { + if(argumentsContainNoLocal(args)) + { + MessageFilter filter = new NoLocalFilter(queue); + + if(argumentsContainJMSSelector(args)) + { + filter = new CompoundFilter(filter, createJMSSelectorFilter(args)); + } + return filter; + } + else + { + return createJMSSelectorFilter(args); + } + + } + + private MessageFilter createJMSSelectorFilter(FieldTable args) throws AMQInvalidArgumentException + { final String selectorString = args.getString(AMQPFilterTypes.JMS_SELECTOR.getValue()); WeakReference<JMSSelectorFilter> selectorRef = _selectorCache.get(selectorString); JMSSelectorFilter selector = null; if(selectorRef == null || (selector = selectorRef.get())==null) { - selector = new JMSSelectorFilter(selectorString); + try + { + selector = new JMSSelectorFilter(selectorString); + } + catch (ParseException e) + { + throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selectorString + "\"", e); + } + catch (SelectorParsingException e) + { + throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selectorString + "\"", e); + } + catch (TokenMgrError e) + { + throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selectorString + "\"", e); + } _selectorCache.put(selectorString, new WeakReference<JMSSelectorFilter>(selector)); } return selector; } - private static boolean argumentsContainSelector(final FieldTable args) + private static boolean argumentsContainFilter(final FieldTable args) { - return args != null && args.containsKey(AMQPFilterTypes.JMS_SELECTOR.getValue()) && args.getString(AMQPFilterTypes.JMS_SELECTOR.getValue()).trim().length() != 0; + return argumentsContainNoLocal(args) || argumentsContainJMSSelector(args); } + private static boolean argumentsContainNoLocal(final FieldTable args) + { + return args != null + && args.containsKey(AMQPFilterTypes.NO_LOCAL.getValue()) + && Boolean.TRUE.equals(args.get(AMQPFilterTypes.NO_LOCAL.getValue())); + } + + private static boolean argumentsContainJMSSelector(final FieldTable args) + { + return args != null && (args.containsKey(AMQPFilterTypes.JMS_SELECTOR.getValue()) + && args.getString(AMQPFilterTypes.JMS_SELECTOR.getValue()).trim().length() != 0); + } + + public ArrayList<BaseQueue> doRoute(InboundMessage payload) { @@ -251,6 +311,28 @@ public class TopicExchange extends AbstractExchange } } + public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue) + { + Binding binding = new Binding(null, bindingKey, queue, this, arguments); + if (arguments == null) + { + return _bindings.containsKey(binding); + } + else + { + FieldTable o = _bindings.get(binding); + if (o != null) + { + return arguments.equals(FieldTable.convertToMap(o)); + } + else + { + return false; + } + } + + } + public boolean isBound(AMQShortString routingKey, AMQQueue queue) { return isBound(routingKey, null, queue); @@ -297,11 +379,11 @@ public class TopicExchange extends AbstractExchange result.removeBinding(binding); - if(argumentsContainSelector(bindingArgs)) + if(argumentsContainFilter(bindingArgs)) { try { - result.removeFilteredQueue(binding.getQueue(), createSelectorFilter(bindingArgs)); + result.removeFilteredQueue(binding.getQueue(), createMessageFilter(bindingArgs, binding.getQueue())); } catch (AMQInvalidArgumentException e) { @@ -378,4 +460,96 @@ public class TopicExchange extends AbstractExchange deregisterQueue(binding); } + private static final class NoLocalFilter implements MessageFilter + { + private final AMQQueue _queue; + + public NoLocalFilter(AMQQueue queue) + { + _queue = queue; + } + + public boolean matches(Filterable message) + { + InboundMessage inbound = (InboundMessage) message; + final AMQSessionModel exclusiveOwningSession = _queue.getExclusiveOwningSession(); + return exclusiveOwningSession == null || !exclusiveOwningSession.onSameConnection(inbound); + + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + + if (o == null || getClass() != o.getClass()) + { + return false; + } + + NoLocalFilter that = (NoLocalFilter) o; + + return _queue == null ? that._queue == null : _queue.equals(that._queue); + } + + @Override + public int hashCode() + { + return _queue != null ? _queue.hashCode() : 0; + } + } + + private static final class CompoundFilter implements MessageFilter + { + private MessageFilter _noLocalFilter; + private MessageFilter _jmsSelectorFilter; + + public CompoundFilter(MessageFilter filter, MessageFilter jmsSelectorFilter) + { + _noLocalFilter = filter; + _jmsSelectorFilter = jmsSelectorFilter; + } + + public boolean matches(Filterable message) + { + return _noLocalFilter.matches(message) && _jmsSelectorFilter.matches(message); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + CompoundFilter that = (CompoundFilter) o; + + if (_jmsSelectorFilter != null ? !_jmsSelectorFilter.equals(that._jmsSelectorFilter) : that._jmsSelectorFilter != null) + { + return false; + } + if (_noLocalFilter != null ? !_noLocalFilter.equals(that._noLocalFilter) : that._noLocalFilter != null) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = _noLocalFilter != null ? _noLocalFilter.hashCode() : 0; + result = 31 * result + (_jmsSelectorFilter != null ? _jmsSelectorFilter.hashCode() : 0); + return result; + } + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java index 620c3ce140..481a377fc4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeMBean.java @@ -20,16 +20,20 @@ */ package org.apache.qpid.server.exchange; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.server.binding.Binding; import javax.management.JMException; -import javax.management.openmbean.*; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.HashMap; -import java.util.ArrayList; /** TopicExchangeMBean class implements the management interface for the Topic exchanges. */ @MBeanDescription("Management Bean for Topic Exchange") @@ -47,7 +51,7 @@ final class TopicExchangeMBean extends AbstractExchangeMBean<TopicExchange> /** returns exchange bindings in tabular form */ public TabularData bindings() throws OpenDataException { - TabularDataSupport bindingList = new TabularDataSupport(_bindinglistDataType); + TabularDataSupport bindingList = new TabularDataSupport(getBindinglistDataType()); Map<String, List<String>> bindingData = new HashMap<String, List<String>>(); for (Binding binding : getExchange().getBindings()) { @@ -65,7 +69,7 @@ final class TopicExchangeMBean extends AbstractExchangeMBean<TopicExchange> { Object[] bindingItemValues = {entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]) }; CompositeData bindingCompositeData = - new CompositeDataSupport(_bindingDataType, + new CompositeDataSupport(getBindingDataType(), COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), bindingItemValues); bindingList.put(bindingCompositeData); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderKey.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderKey.java deleted file mode 100644 index 8fdb91cbef..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderKey.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.apache.qpid.server.exchange.headers; - -import org.apache.qpid.framing.AMQShortString; - -/* -* -* 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. -* -*/ -public class HeaderKey -{ - public static final HeaderKey UNKNOWN = new HeaderKey(new AMQShortString("<< UNKNOWN >>")); - private AMQShortString _key; - - public HeaderKey(final AMQShortString key) - { - _key = key; - } - - public String toString() - { - return _key.toString(); - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderKeyDictionary.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderKeyDictionary.java deleted file mode 100644 index 7be99a88c9..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderKeyDictionary.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.apache.qpid.server.exchange.headers; - -import org.apache.qpid.framing.AMQShortString; - -import java.util.Map; -import java.util.HashMap; - -/* -* -* 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. -* -*/ -public class HeaderKeyDictionary -{ - - private final Map<AMQShortString, HeaderKey> _dictionary = new HashMap<AMQShortString, HeaderKey>(); - - - public HeaderKey get(final AMQShortString key) - { - HeaderKey headerKey = _dictionary.get(key); - return headerKey == null ? HeaderKey.UNKNOWN : headerKey; - } - - public HeaderKey getOrCreate(final AMQShortString key) - { - HeaderKey headerKey = _dictionary.get(key); - if(headerKey == null) - { - headerKey = new HeaderKey(key); - _dictionary.put(key, headerKey); - } - return headerKey; - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderMatcherResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderMatcherResult.java deleted file mode 100644 index 518064bb29..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeaderMatcherResult.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.apache.qpid.server.exchange.headers; - -/* -* -* 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. -* -*/ -public class HeaderMatcherResult -{ -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeadersMatcherDFAState.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeadersMatcherDFAState.java deleted file mode 100644 index 9da93d483a..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeadersMatcherDFAState.java +++ /dev/null @@ -1,339 +0,0 @@ -package org.apache.qpid.server.exchange.headers; - -import org.apache.qpid.framing.AMQTypedValue; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.exchange.topic.TopicMatcherDFAState; -import org.apache.qpid.server.exchange.topic.TopicWord; -import org.apache.qpid.server.exchange.topic.TopicMatcherResult; - -import java.util.*; - -/* -* -* 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. -* -*/ -public class HeadersMatcherDFAState -{ - - - private final Collection<HeaderMatcherResult> _results; - private final Map<HeaderKey, Map<AMQTypedValue,HeadersMatcherDFAState>> _nextStateMap; - private final HeaderKeyDictionary _dictionary; - - public HeadersMatcherDFAState(Map<HeaderKey, Map<AMQTypedValue,HeadersMatcherDFAState>> nextStateMap, - Collection<HeaderMatcherResult> results, - HeaderKeyDictionary dictionary) - { - _nextStateMap = nextStateMap; - _results = results; - _dictionary = dictionary; - } - - - public Collection<HeaderMatcherResult> match(final FieldTable table) - { - return match(table.iterator()); - } - - - - public Collection<HeaderMatcherResult> match(Iterator<Map.Entry<AMQShortString,AMQTypedValue>> fieldTableIterator) - { - - if(_nextStateMap.isEmpty()) - { - return _results; - } - - while(fieldTableIterator.hasNext()) - { - - Map.Entry<AMQShortString, AMQTypedValue> fieldTableEntry = fieldTableIterator.next(); - HeaderKey key = _dictionary.get(fieldTableEntry.getKey()); - if(key != HeaderKey.UNKNOWN) - { - Map<AMQTypedValue, HeadersMatcherDFAState> valueToStateMap = _nextStateMap.get(key); - - if(valueToStateMap != null) - { - HeadersMatcherDFAState nextState = valueToStateMap.get(fieldTableEntry.getValue()); - - if(nextState == null) - { - nextState = valueToStateMap.get(null); - } - if(nextState != null && nextState != this) - { - return nextState.match(fieldTableIterator); - } - } - - } - } - - return _results; - - } - - - HeadersMatcherDFAState mergeStateMachines(HeadersMatcherDFAState otherStateMachine) - { - - assert(otherStateMachine._dictionary == _dictionary); - - Map<Set<HeadersMatcherDFAState>, HeadersMatcherDFAState> newStateMap= new HashMap<Set<HeadersMatcherDFAState>, HeadersMatcherDFAState>(); - - Collection<HeaderMatcherResult> results; - - if(_results.isEmpty()) - { - results = otherStateMachine._results; - } - else if(otherStateMachine._results.isEmpty()) - { - results = _results; - } - else - { - results = new HashSet<HeaderMatcherResult>(_results); - results.addAll(otherStateMachine._results); - } - - - final Map<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>> newNextStateMap = new HashMap<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>>(); - - HeadersMatcherDFAState newState = new HeadersMatcherDFAState(newNextStateMap, results, _dictionary); - - - Set<HeadersMatcherDFAState> oldStates = new HashSet<HeadersMatcherDFAState>(); - oldStates.add(this); - oldStates.add(otherStateMachine); - - newStateMap.put(oldStates, newState); - - mergeStateMachines(oldStates, newNextStateMap, newStateMap); - - return newState; - - - } - - private void mergeStateMachines(final Set<HeadersMatcherDFAState> oldStates, - final Map<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>> newNextStateMap, - final Map<Set<HeadersMatcherDFAState>, HeadersMatcherDFAState> newStateMap) - { - Map<HeaderKey, Map<AMQTypedValue, Set<HeadersMatcherDFAState>>> nfaMap = new HashMap<HeaderKey, Map<AMQTypedValue, Set<HeadersMatcherDFAState>>>(); - - Set<HeaderKey> distinctKeys = new HashSet<HeaderKey>(); - - for(HeadersMatcherDFAState state : oldStates) - { - Map<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>> map = state._nextStateMap; - - for(Map.Entry<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>> entry : map.entrySet()) - { - Map<AMQTypedValue, Set<HeadersMatcherDFAState>> valueToStatesMap = nfaMap.get(entry.getKey()); - - if(valueToStatesMap == null) - { - valueToStatesMap = new HashMap<AMQTypedValue, Set<HeadersMatcherDFAState>>(); - nfaMap.put(entry.getKey(), valueToStatesMap); - } - - for(Map.Entry<AMQTypedValue, HeadersMatcherDFAState> valueToStateEntry : entry.getValue().entrySet()) - { - Set<HeadersMatcherDFAState> states = valueToStatesMap.get(valueToStateEntry.getKey()); - if(states == null) - { - states = new HashSet<HeadersMatcherDFAState>(); - valueToStatesMap.put(valueToStateEntry.getKey(),states); - } - states.add(valueToStateEntry.getValue()); - } - - distinctKeys.add(entry.getKey()); - } - } - - Map<HeaderKey, Set<HeadersMatcherDFAState>> anyValueStates = new HashMap<HeaderKey, Set<HeadersMatcherDFAState>>(); - - for(HeaderKey distinctKey : distinctKeys) - { - Map<AMQTypedValue, Set<HeadersMatcherDFAState>> valueToStateMap = nfaMap.get(distinctKey); - if(valueToStateMap != null) - { - Set<HeadersMatcherDFAState> statesForKeyDefault = valueToStateMap.get(null); - if(statesForKeyDefault != null) - { - anyValueStates.put(distinctKey, statesForKeyDefault); - } - } - } - - // add the defaults for "null" to all other specified values of a given header key - - for( Map.Entry<HeaderKey,Map<AMQTypedValue,Set<HeadersMatcherDFAState>>> entry : nfaMap.entrySet()) - { - Map<AMQTypedValue, Set<HeadersMatcherDFAState>> valueToStatesMap = entry.getValue(); - for(Map.Entry<AMQTypedValue, Set<HeadersMatcherDFAState>> valueToStates : valueToStatesMap.entrySet()) - { - if(valueToStates.getKey() != null) - { - - - Set<HeadersMatcherDFAState> defaults = anyValueStates.get(entry.getKey()); - if(defaults != null) - { - valueToStates.getValue().addAll(defaults); - } - } - } - } - - // if a given header key is not mentioned in the map of a machine; then that machine would stay at the same state - // for that key. - for(HeaderKey distinctKey : distinctKeys) - { - Map<AMQTypedValue, Set<HeadersMatcherDFAState>> valueToStatesMap = nfaMap.get(distinctKey); - for(HeadersMatcherDFAState oldState : oldStates) - { - if(!oldState._nextStateMap.containsKey(distinctKey)) - { - for(Set<HeadersMatcherDFAState> endStates : valueToStatesMap.values()) - { - endStates.add(oldState); - } - } - } - } - - - - - for(Map.Entry<HeaderKey,Map<AMQTypedValue,Set<HeadersMatcherDFAState>>> transitionClass : nfaMap.entrySet()) - { - Map<AMQTypedValue, HeadersMatcherDFAState> valueToDFAState = newNextStateMap.get(transitionClass.getKey()); - if(valueToDFAState == null) - { - valueToDFAState = new HashMap<AMQTypedValue, HeadersMatcherDFAState>(); - newNextStateMap.put(transitionClass.getKey(), valueToDFAState); - } - - for(Map.Entry<AMQTypedValue,Set<HeadersMatcherDFAState>> transition : transitionClass.getValue().entrySet()) - { - Set<HeadersMatcherDFAState> destinations = transition.getValue(); - - - HeadersMatcherDFAState nextState = newStateMap.get(destinations); - - if(nextState == null) - { - - if(destinations.size() == 1) - { - nextState = destinations.iterator().next(); - newStateMap.put(destinations, nextState); - } - else - { - Collection<HeaderMatcherResult> results; - - Set<Collection<HeaderMatcherResult>> resultSets = new HashSet<Collection<HeaderMatcherResult>>(); - for(HeadersMatcherDFAState destination : destinations) - { - resultSets.add(destination._results); - } - resultSets.remove(Collections.EMPTY_SET); - if(resultSets.size() == 0) - { - results = Collections.EMPTY_SET; - } - else if(resultSets.size() == 1) - { - results = resultSets.iterator().next(); - } - else - { - results = new HashSet<HeaderMatcherResult>(); - for(Collection<HeaderMatcherResult> oldResult : resultSets) - { - results.addAll(oldResult); - } - } - - final Map<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>> nextStateMap = new HashMap<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>>(); - - nextState = new HeadersMatcherDFAState(nextStateMap, results, _dictionary); - newStateMap.put(destinations, nextState); - - mergeStateMachines( - destinations, - nextStateMap, - newStateMap); - - - } - - - } - valueToDFAState.put(transition.getKey(),nextState); - } - } - - - - final ArrayList<HeaderKey> removeKeyList = new ArrayList<HeaderKey>(); - - for(Map.Entry<HeaderKey,Map<AMQTypedValue,HeadersMatcherDFAState>> entry : _nextStateMap.entrySet()) - { - final ArrayList<AMQTypedValue> removeValueList = new ArrayList<AMQTypedValue>(); - - for(Map.Entry<AMQTypedValue,HeadersMatcherDFAState> valueToDFAState : entry.getValue().entrySet()) - { - if(valueToDFAState.getValue() == this) - { - HeadersMatcherDFAState defaultState = entry.getValue().get(null); - if(defaultState == null || defaultState == this) - { - removeValueList.add(valueToDFAState.getKey()); - } - } - } - - for(AMQTypedValue removeValue : removeValueList) - { - entry.getValue().remove(removeValue); - } - - if(entry.getValue().isEmpty()) - { - removeKeyList.add(entry.getKey()); - } - - } - - for(HeaderKey removeKey : removeKeyList) - { - _nextStateMap.remove(removeKey); - } - - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeadersParser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeadersParser.java deleted file mode 100644 index d76b163fa1..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/headers/HeadersParser.java +++ /dev/null @@ -1,315 +0,0 @@ -package org.apache.qpid.server.exchange.headers; - -import org.apache.qpid.framing.*; - -import java.util.*; - -/* -* -* 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. -* -*/ -public class HeadersParser -{ - - private final HeaderKeyDictionary _dictionary = new HeaderKeyDictionary(); - private static final AMQShortString MATCHING_TYPE_KEY = new AMQShortString("x-match"); - private static final String ANY_MATCHING = "any"; - private static final AMQShortString RESERVED_KEY_PREFIX = new AMQShortString("x-"); - - - HeadersMatcherDFAState createStateMachine(FieldTable bindingArguments, HeaderMatcherResult result) - { - String matchingType = bindingArguments.getString(MATCHING_TYPE_KEY); - boolean matchAny = matchingType.equalsIgnoreCase(ANY_MATCHING); - if(matchAny) - { - return createStateMachineForAnyMatch(bindingArguments, result); - } - else - { - return createStateMachineForAllMatch(bindingArguments, result); - } - - - } - - - private HeadersMatcherDFAState createStateMachineForAnyMatch(final FieldTable bindingArguments, - final HeaderMatcherResult result) - { - - // DFAs for "any" matches have only two states, "not-matched" and "matched"... they start in the former - // and upon meeting any of the criteria they move to the latter - - //noinspection unchecked - final HeadersMatcherDFAState successState = - new HeadersMatcherDFAState(Collections.EMPTY_MAP,Collections.singleton(result),_dictionary); - - Map<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>> nextStateMap = - new HashMap<HeaderKey, Map<AMQTypedValue, HeadersMatcherDFAState>>(); - - Set<AMQShortString> seenKeys = new HashSet<AMQShortString>(); - - Iterator<Map.Entry<AMQShortString, AMQTypedValue>> tableIterator = bindingArguments.iterator(); - - while(tableIterator.hasNext()) - { - final Map.Entry<AMQShortString, AMQTypedValue> entry = tableIterator.next(); - final AMQShortString key = entry.getKey(); - final AMQTypedValue value = entry.getValue(); - - - if(seenKeys.add(key) && !key.startsWith(RESERVED_KEY_PREFIX)) - { - final AMQType type = value.getType(); - - final HeaderKey headerKey = _dictionary.getOrCreate(key); - final Map<AMQTypedValue, HeadersMatcherDFAState> valueMap; - - if(type == AMQType.VOID || - ((type == AMQType.ASCII_STRING || type == AMQType.WIDE_STRING) && ((CharSequence)value.getValue()).length() == 0)) - { - valueMap = Collections.singletonMap(null,successState); - - } - else - { - valueMap = Collections.singletonMap(value,successState); - } - nextStateMap.put(headerKey,valueMap); - - } - - } - - if(seenKeys.size() == 0) - { - return successState; - } - else - { - return new HeadersMatcherDFAState(nextStateMap,Collections.EMPTY_SET,_dictionary); - } - - - } - - - private HeadersMatcherDFAState createStateMachineForAllMatch(final FieldTable bindingArguments, - final HeaderMatcherResult result) - { - // DFAs for "all" matches have a "success" state, a "fail" state, and states for every subset of - // matches which are possible, starting with the empty subset. For example if we have a binding - // { x-match="all" - // a=1 - // b=1 - // c=1 - // d=1 } - // Then we would have the following states - // (1) Seen none of a, b, c, or d - // (2) Seen a=1 ; none of b,c, or d - // (3) Seen b=1 ; none of a,c, or d - // (4) Seen c=1 ; none of a,b, or d - // (5) Seen d=1 ; none of a,b, or c - // (6) Seen a=1,b=1 ; none of c,d - // (7) Seen a=1,c=1 ; none of b,d - // (8) Seen a=1,d=1 ; none of b,c - // (9) Seen b=1,c=1 ; none of a,d - //(10) Seen b=1,d=1 ; none of c,d - //(11) Seen c=1,d=1 ; none of a,b - //(12) Seen a=1,b=1,c=1 ; not d - //(13) Seen a=1,b=1,d=1 ; not c - //(14) Seen a=1,c=1,d=1 ; not b - //(15) Seen b=1,c=1,d=1 ; not a - //(16) success - //(17) fail - // - // All states but (16) can transition to (17); additionally: - // (1) can transition to (2),(3),(4),(5) - // (2) can transition to (6),(7),(8) - // (3) can transition to (6),(9),(10) - // (4) can transition to (7),(9),(11) - // (5) can transition to (8),(10),(11) - // (6) can transition to (12),(13) - // (7) can transition to (12),(14) - // (8) can transition to (13),(14) - // (9) can transition to (12),(15) - //(10) can transition to (13),(15) - //(11) can transition to (14),(15) - //(12)-(15) can transition to (16) - - Set<AMQShortString> seenKeys = new HashSet<AMQShortString>(); - List<KeyValuePair> requiredTerms = new ArrayList<KeyValuePair>(bindingArguments.size()); - - Iterator<Map.Entry<AMQShortString, AMQTypedValue>> tableIterator = bindingArguments.iterator(); - - - - while(tableIterator.hasNext()) - { - final Map.Entry<AMQShortString, AMQTypedValue> entry = tableIterator.next(); - final AMQShortString key = entry.getKey(); - final AMQTypedValue value = entry.getValue(); - - - if(seenKeys.add(key) && !key.startsWith(RESERVED_KEY_PREFIX)) - { - final AMQType type = value.getType(); - - if(type == AMQType.VOID || - ((type == AMQType.ASCII_STRING || type == AMQType.WIDE_STRING) && ((CharSequence)value.getValue()).length() == 0)) - { - requiredTerms.add(new KeyValuePair(_dictionary.getOrCreate(key),null)); - } - else - { - requiredTerms.add(new KeyValuePair(_dictionary.getOrCreate(key),value)); - } - } - - } - - final HeadersMatcherDFAState successState = - new HeadersMatcherDFAState(Collections.EMPTY_MAP,Collections.singleton(result),_dictionary); - - final HeadersMatcherDFAState failState = - new HeadersMatcherDFAState(Collections.EMPTY_MAP,Collections.EMPTY_SET,_dictionary); - - Map<Set<KeyValuePair>, HeadersMatcherDFAState> notSeenTermsToStateMap = - new HashMap<Set<KeyValuePair>, HeadersMatcherDFAState>(); - - notSeenTermsToStateMap.put(Collections.EMPTY_SET, successState); - - - final int numberOfTerms = requiredTerms.size(); - - for(int numMissingTerms = 1; numMissingTerms <= numberOfTerms; numMissingTerms++) - { - int[] pos = new int[numMissingTerms]; - for(int i = 0; i < numMissingTerms; i++) - { - pos[i] = i; - } - - final int maxTermValue = (numberOfTerms - (numMissingTerms - 1)); - - while(pos[0] < maxTermValue) - { - - Set<KeyValuePair> stateSet = new HashSet<KeyValuePair>(); - for(int posIndex = 0; posIndex < pos.length; posIndex++) - { - stateSet.add(requiredTerms.get(pos[posIndex])); - } - - final Map<HeaderKey, Map<AMQTypedValue,HeadersMatcherDFAState>> nextStateMap = - new HashMap<HeaderKey, Map<AMQTypedValue,HeadersMatcherDFAState>>(); - - - for(int posIndex = 0; posIndex < pos.length; posIndex++) - { - KeyValuePair nextTerm = requiredTerms.get(pos[posIndex]); - HashSet<KeyValuePair> nextStateSet = - new HashSet<KeyValuePair>(stateSet); - nextStateSet.remove(nextTerm); - - Map<AMQTypedValue, HeadersMatcherDFAState> valueToStateMap = - new HashMap<AMQTypedValue, HeadersMatcherDFAState>(); - nextStateMap.put(nextTerm._key, valueToStateMap); - - valueToStateMap.put( nextTerm._value,notSeenTermsToStateMap.get(nextStateSet)); - if(nextTerm._value != null) - { - valueToStateMap.put(null, failState); - } - - - } - - - HeadersMatcherDFAState newState = new HeadersMatcherDFAState(nextStateMap, Collections.EMPTY_SET, _dictionary); - - notSeenTermsToStateMap.put(stateSet, newState); - - int i = numMissingTerms; - while(i-- != 0) - { - if(++pos[i] <= numberOfTerms -(numMissingTerms-i)) - { - int k = pos[i]; - for(int j = i+1; j < numMissingTerms; j++) - { - pos[j] = ++k; - } - break; - } - } - } - - - - - } - - - return notSeenTermsToStateMap.get(new HashSet<KeyValuePair>(requiredTerms)); - - - - } - - public final static class KeyValuePair - { - public final HeaderKey _key; - public final AMQTypedValue _value; - private final int _hashCode; - - public KeyValuePair(final HeaderKey key, final AMQTypedValue value) - { - _key = key; - _value = value; - int hash = (1 + 31 * _key.hashCode()); - if(_value != null) - { - hash+=_value.hashCode(); - } - _hashCode = hash; - } - - public int hashCode() - { - return _hashCode; - } - - public boolean equals(Object o) - { - assert o != null; - assert o instanceof KeyValuePair; - KeyValuePair other = (KeyValuePair)o; - return (_key == other._key) && (_value == null ? other._value == null : _value.equals(other._value)); - } - - - public String toString() - { - return "{" + _key + " -> " + _value + "}"; - } - - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java index d8b09a7841..44d5f7f1d0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicExchangeResult.java @@ -20,10 +20,10 @@ */ package org.apache.qpid.server.exchange.topic; -import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.filter.MessageFilter; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.queue.AMQQueue; import java.util.ArrayList; import java.util.Collection; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java index 4446536d4c..dfe4d85320 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicMatcherDFAState.java @@ -3,7 +3,17 @@ package org.apache.qpid.server.exchange.topic; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.AMQShortStringTokenizer; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicInteger; /* @@ -246,25 +256,25 @@ public class TopicMatcherDFAState transitions.append("[ "); transitions.append(entry.getKey()); transitions.append("\t ->\t "); - transitions.append(entry.getValue()._id); + transitions.append(entry.getValue().getId()); transitions.append(" ]\n"); } - return "[ State " + _id + " ]\n" + transitions + "\n"; + return "[ State " + getId() + " ]\n" + transitions + "\n"; } public String reachableStates() { - StringBuilder result = new StringBuilder("Start state: " + _id + "\n"); + StringBuilder result = new StringBuilder("Start state: " + getId() + "\n"); SortedSet<TopicMatcherDFAState> reachableStates = new TreeSet<TopicMatcherDFAState>(new Comparator<TopicMatcherDFAState>() { public int compare(final TopicMatcherDFAState o1, final TopicMatcherDFAState o2) { - return o1._id - o2._id; + return o1.getId() - o2.getId(); } }); reachableStates.add(this); @@ -292,4 +302,9 @@ public class TopicMatcherDFAState return result.toString(); } + + int getId() + { + return _id; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java index 7e7cb6c0ae..aac696ae2d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicNormalizer.java @@ -22,10 +22,9 @@ package org.apache.qpid.server.exchange.topic; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.AMQShortStringTokenizer; -import org.apache.qpid.server.exchange.TopicExchange; -import java.util.List; import java.util.ArrayList; +import java.util.List; public class TopicNormalizer { @@ -37,6 +36,10 @@ public class TopicNormalizer private static final AMQShortString AMQP_STAR_TOKEN = new AMQShortString("*"); private static final AMQShortString AMQP_HASH_TOKEN = new AMQShortString("#"); + private TopicNormalizer() + { + } + public static AMQShortString normalize(AMQShortString routingKey) { if(routingKey == null) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java index 3e9facf412..1cb4301838 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicParser.java @@ -3,9 +3,15 @@ package org.apache.qpid.server.exchange.topic; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.AMQShortStringTokenizer; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicReference; -import java.io.IOException; /* * @@ -52,14 +58,43 @@ public class TopicParser } + public TopicWord getWord() + { + return _word; + } + + public boolean isSelfTransition() + { + return _selfTransition; + } + + public int getPosition() + { + return _position; + } + + public boolean isEndState() + { + return _endState; + } + + public boolean isFollowedByAnyLoop() + { + return _followedByAnyLoop; + } + + public void setFollowedByAnyLoop(boolean followedByAnyLoop) + { + _followedByAnyLoop = followedByAnyLoop; + } } private static final Position ERROR_POSITION = new Position(Integer.MAX_VALUE,null, true, false); private static class SimpleState { - Set<Position> _positions; - Map<TopicWord, SimpleState> _nextState; + private Set<Position> _positions; + private Map<TopicWord, SimpleState> _nextState; } @@ -180,11 +215,11 @@ public class TopicParser while(followedByWildcards && n<(positionCount+1)) { - if(positions[n]._selfTransition) + if(positions[n].isSelfTransition()) { break; } - else if(positions[n]._word!=TopicWord.ANY_WORD) + else if(positions[n].getWord() !=TopicWord.ANY_WORD) { followedByWildcards = false; } @@ -192,7 +227,7 @@ public class TopicParser } - positions[p]._followedByAnyLoop = followedByWildcards && (n!= positionCount+1); + positions[p].setFollowedByAnyLoop(followedByWildcards && (n!= positionCount+1)); } @@ -221,7 +256,7 @@ public class TopicParser for(Position p : simpleStates[i]._positions) { - if(p._endState) + if(p.isEndState()) { endState = true; break; @@ -267,7 +302,7 @@ public class TopicParser for(Position pos : state._positions) { - if(pos._selfTransition) + if(pos.isSelfTransition()) { Set<Position> dest = transitions.get(TopicWord.ANY_WORD); if(dest == null) @@ -278,14 +313,14 @@ public class TopicParser dest.add(pos); } - final int nextPos = pos._position + 1; + final int nextPos = pos.getPosition() + 1; Position nextPosition = nextPos == positions.length ? ERROR_POSITION : positions[nextPos]; - Set<Position> dest = transitions.get(pos._word); + Set<Position> dest = transitions.get(pos.getWord()); if(dest == null) { dest = new HashSet<Position>(); - transitions.put(pos._word,dest); + transitions.put(pos.getWord(),dest); } dest.add(nextPosition); @@ -312,7 +347,7 @@ public class TopicParser Position loopingTerminal = null; for(Position destPos : dest.getValue()) { - if(destPos._selfTransition && destPos._endState) + if(destPos.isSelfTransition() && destPos.isEndState()) { loopingTerminal = destPos; break; @@ -328,9 +363,9 @@ public class TopicParser Position anyLoop = null; for(Position destPos : dest.getValue()) { - if(destPos._followedByAnyLoop) + if(destPos.isFollowedByAnyLoop()) { - if(anyLoop == null || anyLoop._position<destPos._position) + if(anyLoop == null || anyLoop.getPosition() < destPos.getPosition()) { anyLoop = destPos; } @@ -341,7 +376,7 @@ public class TopicParser Collection<Position> removals = new ArrayList<Position>(); for(Position destPos : dest.getValue()) { - if(destPos._position < anyLoop._position) + if(destPos.getPosition() < anyLoop.getPosition()) { removals.add(destPos); } @@ -421,193 +456,4 @@ public class TopicParser } - public static void main(String[] args) - { - - printMatches("#.b.*.*.*.*.*.h.#.j.*.*.*.*.*.*.q.#.r.*.*.*.*.*.*.*.*","a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z"); - printMatches(new String[]{ - "#.a.#", - "#.b.#", - "#.c.#", - "#.d.#", - "#.e.#", - "#.f.#", - "#.g.#", - "#.h.#", - "#.i.#", - "#.j.#", - "#.k.#", - "#.l.#", - "#.m.#", - "#.n.#", - "#.o.#", - "#.p.#", - "#.q.#" - - }, "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z"); -/* - printMatches(new String[]{ - "#.a.#", - "#.b.#", - "#.c.#", - "#.d.#", - "#.e.#", - "#.f.#", - "#.g.#", - "#.h.#", - "#.i.#", - "#.j.#", - "#.k.#", - "#.l.#", - "#.m.#", - "#.n.#", - "#.o.#", - "#.p.#", - "#.q.#", - "#.r.#", - "#.s.#", - "#.t.#", - "#.u.#", - "#.v.#", - "#.w.#", - "#.x.#", - "#.y.#", - "#.z.#" - - - },"a.b"); - - printMatches("#.b.*.*.*.*.*.h.#.j.*.*.*.*.*.p.#.r.*.*.*.*.*","a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z"); - printMatches("#.b.*.*.*.*.*.h.#.j.*.*.*.*.*.p.#.r.*.*.*.*.*.*.*.*","a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z"); - printMatches("a.#.b.#","a.b.b.b.b.b.b.b.c"); - -*/ - - printMatches("",""); - printMatches("a","a"); - printMatches("a",""); - printMatches("","a"); - printMatches("a.b","a.b"); - printMatches("a","a.b"); - printMatches("a.b","a"); - printMatches("*","a"); - printMatches("*.b","a.b"); - printMatches("*.*","a.b"); - printMatches("a.*","a.b"); - printMatches("a.*.#","a.b"); - printMatches("a.#.b","a.b"); - - printMatches("#.b","a"); - printMatches("#.b","a.b"); - printMatches("#.a.b","a.b"); - - - printMatches("#",""); - printMatches("#","a"); - printMatches("#","a.b"); - printMatches("#.#","a.b"); - printMatches("#.*","a.b"); - - printMatches("#.a.b","a.b"); - printMatches("a.b.#","a.b"); - printMatches("a.#","a.b"); - printMatches("#.*.#","a.b"); - printMatches("#.*.b.#","a.b"); - printMatches("#.a.*.#","a.b"); - printMatches("#.a.#.b.#","a.b"); - printMatches("#.*.#.*.#","a.b"); - printMatches("*.#.*.#","a.b"); - printMatches("#.*.#.*","a.b"); - - - printMatches(new String[]{"a.#.b.#","a.*.#.b.#"},"a.b.b.b.b.b.b.b.c"); - - - printMatches(new String[]{"a.b", "a.c"},"a.b"); - printMatches(new String[]{"a.#", "a.c", "#.b"},"a.b"); - printMatches(new String[]{"a.#", "a.c", "#.b", "#", "*.*"},"a.b"); - - printMatches(new String[]{"a.b.c.d.e.#", "a.b.c.d.#", "a.b.c.d.*", "a.b.c.#", "#.e", "a.*.c.d.e","#.c.*.#.*.*"},"a.b.c.d.e"); - printMatches(new String[]{"a.b.c.d.e.#", "a.b.c.d.#", "a.b.c.d.*", "a.b.c.#", "#.e", "a.*.c.d.e","#.c.*.#.*.*"},"a.b.c.d.f.g"); - - - - - } - - private static void printMatches(final String[] bindingKeys, final String routingKey) - { - TopicMatcherDFAState sm = null; - Map<TopicMatcherResult, String> resultMap = new HashMap<TopicMatcherResult, String>(); - - TopicParser parser = new TopicParser(); - - long start = System.currentTimeMillis(); - for(int i = 0; i < bindingKeys.length; i++) - { - System.out.println((System.currentTimeMillis() - start) + ":\t" + bindingKeys[i]); - TopicMatcherResult r = new TopicMatcherResult(){}; - resultMap.put(r, bindingKeys[i]); - AMQShortString bindingKeyShortString = new AMQShortString(bindingKeys[i]); - - System.err.println("====================================================="); - System.err.println("Adding binding key: " + bindingKeyShortString); - System.err.println("-----------------------------------------------------"); - - - if(i==0) - { - sm = parser.createStateMachine(bindingKeyShortString, r); - } - else - { - sm = sm.mergeStateMachines(parser.createStateMachine(bindingKeyShortString, r)); - } - System.err.println(sm.reachableStates()); - System.err.println("====================================================="); - try - { - System.in.read(); - } - catch (IOException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - AMQShortString routingKeyShortString = new AMQShortString(routingKey); - - Collection<TopicMatcherResult> results = sm.parse(parser._dictionary, routingKeyShortString); - Collection<String> resultStrings = new ArrayList<String>(); - - for(TopicMatcherResult result : results) - { - resultStrings.add(resultMap.get(result)); - } - - final ArrayList<String> nonMatches = new ArrayList<String>(Arrays.asList(bindingKeys)); - nonMatches.removeAll(resultStrings); - System.out.println("\""+routingKeyShortString+"\" matched with " + resultStrings + " DID NOT MATCH with " + nonMatches); - - - } - - private static void printMatches(String bindingKey, String routingKey) - { - printMatches(new String[] { bindingKey }, routingKey); - } - - - private static boolean matches(String bindingKey, String routingKey) - { - AMQShortString bindingKeyShortString = new AMQShortString(bindingKey); - AMQShortString routingKeyShortString = new AMQShortString(routingKey); - TopicParser parser = new TopicParser(); - - final TopicMatcherResult result = new TopicMatcherResult(){}; - - TopicMatcherDFAState sm = parser.createStateMachine(bindingKeyShortString, result); - return !sm.parse(parser._dictionary,routingKeyShortString).isEmpty(); - - } - } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java index f14d70f8a1..b23b3db272 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/topic/TopicWord.java @@ -2,10 +2,6 @@ package org.apache.qpid.server.exchange.topic; import org.apache.qpid.framing.AMQShortString; -import java.util.Map; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; - /* * * Licensed to the Apache Software Foundation (ASF) under one diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java index 4db6ee3ad2..b58802e1ff 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java @@ -45,9 +45,28 @@ 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.*; - -import java.util.*; +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; @@ -503,7 +522,7 @@ public class Bridge implements BridgeConfig _transaction.enqueue(queues,message, new ServerTransaction.Action() { - BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]); + private BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]); public void postCommit() { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java index a8f75d2b9b..032df8bb0d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java @@ -30,8 +30,15 @@ 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.*; -import org.apache.qpid.util.Strings; +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; @@ -42,7 +49,11 @@ import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; import java.io.IOException; -import java.util.*; +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; @@ -365,8 +376,8 @@ public class BrokerLink implements LinkConfig, ConnectionListener } }; final SaslClient sc = Sasl.createSaslClient(new String[] {"PLAIN"}, null, - _conSettings.getSaslProtocol(), - _conSettings.getSaslServerName(), + getConnectionSettings().getSaslProtocol(), + getConnectionSettings().getSaslServerName(), saslProps, cbh); return sc; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ArithmeticExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ArithmeticExpression.java deleted file mode 100644 index 221d23ef0d..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ArithmeticExpression.java +++ /dev/null @@ -1,275 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.queue.Filterable; - -/** - * An expression which performs an operation on two expression values - */ -public abstract class ArithmeticExpression extends BinaryExpression -{ - - protected static final int INTEGER = 1; - protected static final int LONG = 2; - protected static final int DOUBLE = 3; - - /** - * @param left - * @param right - */ - public ArithmeticExpression(Expression left, Expression right) - { - super(left, right); - } - - public static Expression createPlus(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof String) - { - String text = (String) lvalue; - String answer = text + rvalue; - - return answer; - } - else if (lvalue instanceof Number) - { - return plus((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call plus operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "+"; - } - }; - } - - public static Expression createMinus(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return minus((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call minus operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "-"; - } - }; - } - - public static Expression createMultiply(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return multiply((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call multiply operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "*"; - } - }; - } - - public static Expression createDivide(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return divide((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call divide operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "/"; - } - }; - } - - public static Expression createMod(Expression left, Expression right) - { - return new ArithmeticExpression(left, right) - { - - protected Object evaluate(Object lvalue, Object rvalue) - { - if (lvalue instanceof Number) - { - return mod((Number) lvalue, asNumber(rvalue)); - } - - throw new RuntimeException("Cannot call mod operation on: " + lvalue + " and: " + rvalue); - } - - public String getExpressionSymbol() - { - return "%"; - } - }; - } - - protected Number plus(Number left, Number right) - { - switch (numberType(left, right)) - { - - case INTEGER: - return Integer.valueOf(left.intValue() + right.intValue()); - - case LONG: - return Long.valueOf(left.longValue() + right.longValue()); - - default: - return Double.valueOf(left.doubleValue() + right.doubleValue()); - } - } - - protected Number minus(Number left, Number right) - { - switch (numberType(left, right)) - { - - case INTEGER: - return Integer.valueOf(left.intValue() - right.intValue()); - - case LONG: - return Long.valueOf(left.longValue() - right.longValue()); - - default: - return Double.valueOf(left.doubleValue() - right.doubleValue()); - } - } - - protected Number multiply(Number left, Number right) - { - switch (numberType(left, right)) - { - - case INTEGER: - return Integer.valueOf(left.intValue() * right.intValue()); - - case LONG: - return Long.valueOf(left.longValue() * right.longValue()); - - default: - return Double.valueOf(left.doubleValue() * right.doubleValue()); - } - } - - protected Number divide(Number left, Number right) - { - return Double.valueOf(left.doubleValue() / right.doubleValue()); - } - - protected Number mod(Number left, Number right) - { - return Double.valueOf(left.doubleValue() % right.doubleValue()); - } - - private int numberType(Number left, Number right) - { - if (isDouble(left) || isDouble(right)) - { - return DOUBLE; - } - else if ((left instanceof Long) || (right instanceof Long)) - { - return LONG; - } - else - { - return INTEGER; - } - } - - private boolean isDouble(Number n) - { - return (n instanceof Float) || (n instanceof Double); - } - - protected Number asNumber(Object value) - { - if (value instanceof Number) - { - return (Number) value; - } - else - { - throw new RuntimeException("Cannot convert value: " + value + " into a number"); - } - } - - public Object evaluate(Filterable message) - { - Object lvalue = left.evaluate(message); - if (lvalue == null) - { - return null; - } - - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - return evaluate(lvalue, rvalue); - } - - /** - * @param lvalue - * @param rvalue - * @return - */ - protected abstract Object evaluate(Object lvalue, Object rvalue); - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/BinaryExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/BinaryExpression.java deleted file mode 100644 index 024257bea9..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/BinaryExpression.java +++ /dev/null @@ -1,106 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -/** - * An expression which performs an operation on two expression values. - */ -public abstract class BinaryExpression implements Expression -{ - protected Expression left; - protected Expression right; - - public BinaryExpression(Expression left, Expression right) - { - this.left = left; - this.right = right; - } - - public Expression getLeft() - { - return left; - } - - public Expression getRight() - { - return right; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() - { - return "(" + left.toString() + " " + getExpressionSymbol() + " " + right.toString() + ")"; - } - - /** - * TODO: more efficient hashCode() - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() - { - return toString().hashCode(); - } - - /** - * TODO: more efficient hashCode() - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object o) - { - - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - - return toString().equals(o.toString()); - - } - - /** - * Returns the symbol that represents this binary expression. For example, addition is - * represented by "+" - * - * @return - */ - public abstract String getExpressionSymbol(); - - /** - * @param expression - */ - public void setRight(Expression expression) - { - right = expression; - } - - /** - * @param expression - */ - public void setLeft(Expression expression) - { - left = expression; - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/BooleanExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/BooleanExpression.java deleted file mode 100644 index 06e8664470..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/BooleanExpression.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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import org.apache.qpid.server.queue.Filterable; - -/** - * A BooleanExpression is an expression that always - * produces a Boolean result. - */ -public interface BooleanExpression extends Expression -{ - - /** - * @param message - * @return true if the expression evaluates to Boolean.TRUE. - */ - public boolean matches(Filterable message); - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ComparisonExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ComparisonExpression.java deleted file mode 100644 index aad9d41174..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ComparisonExpression.java +++ /dev/null @@ -1,599 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import java.util.HashSet; -import java.util.List; -import java.util.regex.Pattern; - -import org.apache.qpid.server.queue.Filterable; - -/** - * A filter performing a comparison of two objects - */ -public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression -{ - - public static BooleanExpression createBetween(Expression value, Expression left, Expression right) - { - return LogicExpression.createAND(createGreaterThanEqual(value, left), createLessThanEqual(value, right)); - } - - public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right) - { - return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right)); - } - - private static final HashSet<Character> REGEXP_CONTROL_CHARS = new HashSet<Character>(); - - static - { - REGEXP_CONTROL_CHARS.add('.'); - REGEXP_CONTROL_CHARS.add('\\'); - REGEXP_CONTROL_CHARS.add('['); - REGEXP_CONTROL_CHARS.add(']'); - REGEXP_CONTROL_CHARS.add('^'); - REGEXP_CONTROL_CHARS.add('$'); - REGEXP_CONTROL_CHARS.add('?'); - REGEXP_CONTROL_CHARS.add('*'); - REGEXP_CONTROL_CHARS.add('+'); - REGEXP_CONTROL_CHARS.add('{'); - REGEXP_CONTROL_CHARS.add('}'); - REGEXP_CONTROL_CHARS.add('|'); - REGEXP_CONTROL_CHARS.add('('); - REGEXP_CONTROL_CHARS.add(')'); - REGEXP_CONTROL_CHARS.add(':'); - REGEXP_CONTROL_CHARS.add('&'); - REGEXP_CONTROL_CHARS.add('<'); - REGEXP_CONTROL_CHARS.add('>'); - REGEXP_CONTROL_CHARS.add('='); - REGEXP_CONTROL_CHARS.add('!'); - } - - static class LikeExpression extends UnaryExpression implements BooleanExpression - { - - Pattern likePattern; - - /** - * @param right - */ - public LikeExpression(Expression right, String like, int escape) - { - super(right); - - StringBuffer regexp = new StringBuffer(like.length() * 2); - regexp.append("\\A"); // The beginning of the input - for (int i = 0; i < like.length(); i++) - { - char c = like.charAt(i); - if (escape == (0xFFFF & c)) - { - i++; - if (i >= like.length()) - { - // nothing left to escape... - break; - } - - char t = like.charAt(i); - regexp.append("\\x"); - regexp.append(Integer.toHexString(0xFFFF & t)); - } - else if (c == '%') - { - regexp.append(".*?"); // Do a non-greedy match - } - else if (c == '_') - { - regexp.append("."); // match one - } - else if (REGEXP_CONTROL_CHARS.contains(c)) - { - regexp.append("\\x"); - regexp.append(Integer.toHexString(0xFFFF & c)); - } - else - { - regexp.append(c); - } - } - - regexp.append("\\z"); // The end of the input - - likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL); - } - - /** - * org.apache.activemq.filter.UnaryExpression#getExpressionSymbol() - */ - public String getExpressionSymbol() - { - return "LIKE"; - } - - /** - * org.apache.activemq.filter.Expression#evaluate(MessageEvaluationContext) - */ - public Object evaluate(Filterable message) - { - - Object rv = this.getRight().evaluate(message); - - if (rv == null) - { - return null; - } - - if (!(rv instanceof String)) - { - return - Boolean.FALSE; - // throw new RuntimeException("LIKE can only operate on String identifiers. LIKE attemped on: '" + rv.getClass()); - } - - return likePattern.matcher((String) rv).matches() ? Boolean.TRUE : Boolean.FALSE; - } - - public boolean matches(Filterable message) - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - } - - public static BooleanExpression createLike(Expression left, String right, String escape) - { - if ((escape != null) && (escape.length() != 1)) - { - throw new RuntimeException( - "The ESCAPE string litteral is invalid. It can only be one character. Litteral used: " + escape); - } - - int c = -1; - if (escape != null) - { - c = 0xFFFF & escape.charAt(0); - } - - return new LikeExpression(left, right, c); - } - - public static BooleanExpression createNotLike(Expression left, String right, String escape) - { - return UnaryExpression.createNOT(createLike(left, right, escape)); - } - - public static BooleanExpression createInFilter(Expression left, List elements) - { - - if (!(left instanceof PropertyExpression)) - { - throw new RuntimeException("Expected a property for In expression, got: " + left); - } - - return UnaryExpression.createInExpression((PropertyExpression) left, elements, false); - - } - - public static BooleanExpression createNotInFilter(Expression left, List elements) - { - - if (!(left instanceof PropertyExpression)) - { - throw new RuntimeException("Expected a property for In expression, got: " + left); - } - - return UnaryExpression.createInExpression((PropertyExpression) left, elements, true); - - } - - public static BooleanExpression createIsNull(Expression left) - { - return doCreateEqual(left, ConstantExpression.NULL); - } - - public static BooleanExpression createIsNotNull(Expression left) - { - return UnaryExpression.createNOT(doCreateEqual(left, ConstantExpression.NULL)); - } - - public static BooleanExpression createNotEqual(Expression left, Expression right) - { - return UnaryExpression.createNOT(createEqual(left, right)); - } - - public static BooleanExpression createEqual(Expression left, Expression right) - { - checkEqualOperand(left); - checkEqualOperand(right); - checkEqualOperandCompatability(left, right); - - return doCreateEqual(left, right); - } - - private static BooleanExpression doCreateEqual(Expression left, Expression right) - { - return new EqualExpression(left, right); - } - - public static BooleanExpression createGreaterThan(final Expression left, final Expression right) - { - checkLessThanOperand(left); - checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - protected boolean asBoolean(int answer) - { - return answer > 0; - } - - public String getExpressionSymbol() - { - return ">"; - } - }; - } - - public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) - { - checkLessThanOperand(left); - checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - protected boolean asBoolean(int answer) - { - return answer >= 0; - } - - public String getExpressionSymbol() - { - return ">="; - } - }; - } - - public static BooleanExpression createLessThan(final Expression left, final Expression right) - { - checkLessThanOperand(left); - checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - - protected boolean asBoolean(int answer) - { - return answer < 0; - } - - public String getExpressionSymbol() - { - return "<"; - } - - }; - } - - public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) - { - checkLessThanOperand(left); - checkLessThanOperand(right); - - return new ComparisonExpression(left, right) - { - - protected boolean asBoolean(int answer) - { - return answer <= 0; - } - - public String getExpressionSymbol() - { - return "<="; - } - }; - } - - /** - * Only Numeric expressions can be used in >, >=, < or <= expressions.s - * - * @param expr - */ - public static void checkLessThanOperand(Expression expr) - { - if (expr instanceof ConstantExpression) - { - Object value = ((ConstantExpression) expr).getValue(); - if (value instanceof Number) - { - return; - } - - // Else it's boolean or a String.. - throw new RuntimeException("Value '" + expr + "' cannot be compared."); - } - - if (expr instanceof BooleanExpression) - { - throw new RuntimeException("Value '" + expr + "' cannot be compared."); - } - } - - /** - * Validates that the expression can be used in == or <> expression. - * Cannot not be NULL TRUE or FALSE litterals. - * - * @param expr - */ - public static void checkEqualOperand(Expression expr) - { - if (expr instanceof ConstantExpression) - { - Object value = ((ConstantExpression) expr).getValue(); - if (value == null) - { - throw new RuntimeException("'" + expr + "' cannot be compared."); - } - } - } - - /** - * - * @param left - * @param right - */ - private static void checkEqualOperandCompatability(Expression left, Expression right) - { - if ((left instanceof ConstantExpression) && (right instanceof ConstantExpression)) - { - if ((left instanceof BooleanExpression) && !(right instanceof BooleanExpression)) - { - throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'"); - } - } - } - - /** - * @param left - * @param right - */ - public ComparisonExpression(Expression left, Expression right) - { - super(left, right); - } - - public Object evaluate(Filterable message) - { - Comparable lv = (Comparable) left.evaluate(message); - if (lv == null) - { - return null; - } - - Comparable rv = (Comparable) right.evaluate(message); - if (rv == null) - { - return null; - } - - return compare(lv, rv); - } - - protected Boolean compare(Comparable lv, Comparable rv) - { - Class lc = lv.getClass(); - Class rc = rv.getClass(); - // If the the objects are not of the same type, - // try to convert up to allow the comparison. - if (lc != rc) - { - if (lc == Byte.class) - { - if (rc == Short.class) - { - lv = ((Number) lv).shortValue(); - } - else if (rc == Integer.class) - { - lv = ((Number) lv).intValue(); - } - else if (rc == Long.class) - { - lv = ((Number) lv).longValue(); - } - else if (rc == Float.class) - { - lv = ((Number) lv).floatValue(); - } - else if (rc == Double.class) - { - lv = ((Number) lv).doubleValue(); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Short.class) - { - if (rc == Integer.class) - { - lv = ((Number) lv).intValue(); - } - else if (rc == Long.class) - { - lv = ((Number) lv).longValue(); - } - else if (rc == Float.class) - { - lv = ((Number) lv).floatValue(); - } - else if (rc == Double.class) - { - lv = ((Number) lv).doubleValue(); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Integer.class) - { - if (rc == Long.class) - { - lv = ((Number) lv).longValue(); - } - else if (rc == Float.class) - { - lv = ((Number) lv).floatValue(); - } - else if (rc == Double.class) - { - lv = ((Number) lv).doubleValue(); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Long.class) - { - if (rc == Integer.class) - { - rv = ((Number) rv).longValue(); - } - else if (rc == Float.class) - { - lv = ((Number) lv).floatValue(); - } - else if (rc == Double.class) - { - lv = ((Number) lv).doubleValue(); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Float.class) - { - if (rc == Integer.class) - { - rv = ((Number) rv).floatValue(); - } - else if (rc == Long.class) - { - rv = ((Number) rv).floatValue(); - } - else if (rc == Double.class) - { - lv = ((Number) lv).doubleValue(); - } - else - { - return Boolean.FALSE; - } - } - else if (lc == Double.class) - { - if (rc == Integer.class) - { - rv = ((Number) rv).doubleValue(); - } - else if (rc == Long.class) - { - rv = ((Number) rv).doubleValue(); - } - else if (rc == Float.class) - { - rv = ((Number) rv).doubleValue(); - } - else - { - return Boolean.FALSE; - } - } - else - { - return Boolean.FALSE; - } - } - - return asBoolean(lv.compareTo(rv)) ? Boolean.TRUE : Boolean.FALSE; - } - - protected abstract boolean asBoolean(int answer); - - public boolean matches(Filterable message) - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - - private static class EqualExpression extends ComparisonExpression - { - public EqualExpression(final Expression left, final Expression right) - { - super(left, right); - } - - public Object evaluate(Filterable message) - { - Object lv = left.evaluate(message); - Object rv = right.evaluate(message); - - // Iff one of the values is null - if ((lv == null) ^ (rv == null)) - { - return Boolean.FALSE; - } - - if ((lv == rv) || lv.equals(rv)) - { - return Boolean.TRUE; - } - - if ((lv instanceof Comparable) && (rv instanceof Comparable)) - { - return compare((Comparable) lv, (Comparable) rv); - } - - return Boolean.FALSE; - } - - protected boolean asBoolean(int answer) - { - return answer == 0; - } - - public String getExpressionSymbol() - { - return "="; - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ConstantExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ConstantExpression.java deleted file mode 100644 index 5cc9ca8ef2..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/ConstantExpression.java +++ /dev/null @@ -1,209 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import java.math.BigDecimal; - -import org.apache.qpid.server.queue.Filterable; - -/** - * Represents a constant expression - */ -public class ConstantExpression implements Expression -{ - - static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression - { - public BooleanConstantExpression(Object value) - { - super(value); - } - - public boolean matches(Filterable message) - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - } - - public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null); - public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE); - public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE); - - private Object value; - - public static ConstantExpression createFromDecimal(String text) - { - - // Strip off the 'l' or 'L' if needed. - if (text.endsWith("l") || text.endsWith("L")) - { - text = text.substring(0, text.length() - 1); - } - - Number value; - try - { - value = new Long(text); - } - catch (NumberFormatException e) - { - // The number may be too big to fit in a long. - value = new BigDecimal(text); - } - - long l = value.longValue(); - if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) - { - value = value.intValue(); - } - - return new ConstantExpression(value); - } - - public static ConstantExpression createFromHex(String text) - { - Number value = Long.parseLong(text.substring(2), 16); - long l = value.longValue(); - if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) - { - value = value.intValue(); - } - - return new ConstantExpression(value); - } - - public static ConstantExpression createFromOctal(String text) - { - Number value = Long.parseLong(text, 8); - long l = value.longValue(); - if ((Integer.MIN_VALUE <= l) && (l <= Integer.MAX_VALUE)) - { - value = value.intValue(); - } - - return new ConstantExpression(value); - } - - public static ConstantExpression createFloat(String text) - { - Number value = new Double(text); - - return new ConstantExpression(value); - } - - public ConstantExpression(Object value) - { - this.value = value; - } - - public Object evaluate(Filterable message) - { - return value; - } - - public Object getValue() - { - return value; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() - { - if (value == null) - { - return "NULL"; - } - - if (value instanceof Boolean) - { - return ((Boolean) value) ? "TRUE" : "FALSE"; - } - - if (value instanceof String) - { - return encodeString((String) value); - } - - return value.toString(); - } - - /** - * TODO: more efficient hashCode() - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() - { - return toString().hashCode(); - } - - /** - * TODO: more efficient hashCode() - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object o) - { - - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - - return toString().equals(o.toString()); - - } - - /** - * Encodes the value of string so that it looks like it would look like - * when it was provided in a selector. - * - * @param s - * @return - */ - public static String encodeString(String s) - { - StringBuffer b = new StringBuffer(); - b.append('\''); - for (int i = 0; i < s.length(); i++) - { - char c = s.charAt(i); - if (c == '\'') - { - b.append(c); - } - - b.append(c); - } - - b.append('\''); - - return b.toString(); - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/Expression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/Expression.java deleted file mode 100644 index 97e9915271..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/Expression.java +++ /dev/null @@ -1,36 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import org.apache.qpid.server.queue.Filterable; - -/** - * Represents an expression - */ -public interface Expression -{ - - /** - * @return the value of this expression - */ - public Object evaluate(Filterable message); - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java index dac517150a..56f0a6e08d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/FilterManagerFactory.java @@ -20,12 +20,17 @@ */ package org.apache.qpid.server.filter; -import java.util.Map; +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.filter.SelectorParsingException; +import org.apache.qpid.filter.selector.ParseException; +import org.apache.qpid.filter.selector.TokenMgrError; import org.apache.qpid.framing.FieldTable; -import org.apache.log4j.Logger; + +import java.util.Map; public class FilterManagerFactory @@ -33,6 +38,10 @@ public class FilterManagerFactory private final static Logger _logger = Logger.getLogger(FilterManagerFactory.class); + private FilterManagerFactory() + { + } + //fixme move to a common class so it can be refered to from client code. public static FilterManager createManager(FieldTable filters) throws AMQException @@ -51,7 +60,22 @@ public class FilterManagerFactory if (selector != null && !selector.equals("")) { manager = new SimpleFilterManager(); - manager.add(new JMSSelectorFilter(selector)); + try + { + manager.add(new JMSSelectorFilter(selector)); + } + catch (ParseException e) + { + throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selector + "\"", e); + } + catch (SelectorParsingException e) + { + throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selector + "\"", e); + } + catch (TokenMgrError e) + { + throw new AMQInvalidArgumentException("Cannot parse JMS selector \"" + selector + "\"", e); + } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java index 423bbc244e..47cacdc176 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/JMSSelectorFilter.java @@ -21,8 +21,13 @@ package org.apache.qpid.server.filter; import org.apache.log4j.Logger; -import org.apache.qpid.AMQInvalidArgumentException; -import org.apache.qpid.server.filter.jms.selector.SelectorParser; + +import org.apache.qpid.filter.BooleanExpression; +import org.apache.qpid.filter.FilterableMessage; +import org.apache.qpid.filter.SelectorParsingException; +import org.apache.qpid.filter.selector.ParseException; +import org.apache.qpid.filter.selector.SelectorParser; +import org.apache.qpid.filter.selector.TokenMgrError; import org.apache.qpid.server.queue.Filterable; @@ -33,7 +38,7 @@ public class JMSSelectorFilter implements MessageFilter private String _selector; private BooleanExpression _matcher; - public JMSSelectorFilter(String selector) throws AMQInvalidArgumentException + public JMSSelectorFilter(String selector) throws ParseException, TokenMgrError, SelectorParsingException { _selector = selector; _matcher = new SelectorParser().parse(selector); @@ -41,7 +46,8 @@ public class JMSSelectorFilter implements MessageFilter public boolean matches(Filterable message) { - boolean match = _matcher.matches(message); + + boolean match = _matcher.matches(wrap(message)); if(_logger.isDebugEnabled()) { _logger.debug(message + " match(" + match + ") selector(" + System.identityHashCode(_selector) + "):" + _selector); @@ -49,6 +55,62 @@ public class JMSSelectorFilter implements MessageFilter return match; } + private FilterableMessage wrap(final Filterable message) + { + return new FilterableMessage() + { + public boolean isPersistent() + { + return message.isPersistent(); + } + + public boolean isRedelivered() + { + return message.isRedelivered(); + } + + public Object getHeader(String name) + { + return message.getMessageHeader().getHeader(name); + } + + public String getReplyTo() + { + return message.getMessageHeader().getReplyTo(); + } + + public String getType() + { + return message.getMessageHeader().getType(); + } + + public byte getPriority() + { + return message.getMessageHeader().getPriority(); + } + + public String getMessageId() + { + return message.getMessageHeader().getMessageId(); + } + + public long getTimestamp() + { + return message.getMessageHeader().getTimestamp(); + } + + public String getCorrelationId() + { + return message.getMessageHeader().getCorrelationId(); + } + + public long getExpiration() + { + return message.getMessageHeader().getExpiration(); + } + }; + } + public String getSelector() { return _selector; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/LogicExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/LogicExpression.java deleted file mode 100644 index fdba184da4..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/LogicExpression.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.server.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import org.apache.qpid.server.queue.Filterable; - -/** - * A filter performing a comparison of two objects - */ -public abstract class LogicExpression extends BinaryExpression implements BooleanExpression -{ - - public static BooleanExpression createOR(BooleanExpression lvalue, BooleanExpression rvalue) - { - return new OrExpression(lvalue, rvalue); - } - - public static BooleanExpression createAND(BooleanExpression lvalue, BooleanExpression rvalue) - { - return new AndExpression(lvalue, rvalue); - } - - /** - * @param left - * @param right - */ - public LogicExpression(BooleanExpression left, BooleanExpression right) - { - super(left, right); - } - - public abstract Object evaluate(Filterable message); - - public boolean matches(Filterable message) - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - - private static class OrExpression extends LogicExpression - { - public OrExpression(final BooleanExpression lvalue, final BooleanExpression rvalue) - { - super(lvalue, rvalue); - } - - public Object evaluate(Filterable message) - { - - Boolean lv = (Boolean) left.evaluate(message); - // Can we do an OR shortcut?? - if ((lv != null) && lv.booleanValue()) - { - return Boolean.TRUE; - } - - Boolean rv = (Boolean) right.evaluate(message); - - return (rv == null) ? null : rv; - } - - public String getExpressionSymbol() - { - return "OR"; - } - } - - private static class AndExpression extends LogicExpression - { - public AndExpression(final BooleanExpression lvalue, final BooleanExpression rvalue) - { - super(lvalue, rvalue); - } - - public Object evaluate(Filterable message) - { - - Boolean lv = (Boolean) left.evaluate(message); - - // Can we do an AND shortcut?? - if (lv == null) - { - return null; - } - - if (!lv.booleanValue()) - { - return Boolean.FALSE; - } - - Boolean rv = (Boolean) right.evaluate(message); - - return (rv == null) ? null : rv; - } - - public String getExpressionSymbol() - { - return "AND"; - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/NoConsumerFilter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/NoConsumerFilter.java index 65ddf19fc4..d3e097d22c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/NoConsumerFilter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/NoConsumerFilter.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.filter; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.server.queue.Filterable; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java deleted file mode 100644 index 9848f90ea9..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java +++ /dev/null @@ -1,236 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import java.util.HashMap; - -import org.apache.log4j.Logger; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.CommonContentHeaderProperties; -import org.apache.qpid.server.queue.Filterable; - -/** - * Represents a property expression - */ -public class PropertyExpression implements Expression -{ - // Constants - defined the same as JMS - private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT } - - private static final int DEFAULT_PRIORITY = 4; - - private static final Logger _logger = org.apache.log4j.Logger.getLogger(PropertyExpression.class); - - private static final HashMap<String, Expression> JMS_PROPERTY_EXPRESSIONS = new HashMap<String, Expression>(); - - { - JMS_PROPERTY_EXPRESSIONS.put("JMSDestination", new Expression() - { - public Object evaluate(Filterable message) - { - //TODO - return null; - } - }); - JMS_PROPERTY_EXPRESSIONS.put("JMSReplyTo", new ReplyToExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSType", new TypeExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSDeliveryMode", new DeliveryModeExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSPriority", new PriorityExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSMessageID", new MessageIDExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("AMQMessageID", new MessageIDExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSTimestamp", new TimestampExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSCorrelationID", new CorrelationIdExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSExpiration", new ExpirationExpression()); - - JMS_PROPERTY_EXPRESSIONS.put("JMSRedelivered", new Expression() - { - public Object evaluate(Filterable message) - { - return message.isRedelivered(); - } - }); - } - - private final String name; - private final Expression jmsPropertyExpression; - - public boolean outerTest() - { - return false; - } - - public PropertyExpression(String name) - { - this.name = name; - - - - jmsPropertyExpression = (Expression) JMS_PROPERTY_EXPRESSIONS.get(name); - } - - public Object evaluate(Filterable message) - { - - if (jmsPropertyExpression != null) - { - return jmsPropertyExpression.evaluate(message); - } - else - { - return message.getMessageHeader().getHeader(name); - } - } - - public String getName() - { - return name; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() - { - return name; - } - - /** - * @see java.lang.Object#hashCode() - */ - public int hashCode() - { - return name.hashCode(); - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object o) - { - - if ((o == null) || !this.getClass().equals(o.getClass())) - { - return false; - } - - return name.equals(((PropertyExpression) o).name); - - } - - private static class ReplyToExpression implements Expression - { - public Object evaluate(Filterable message) - { - String replyTo = message.getMessageHeader().getReplyTo(); - return replyTo; - } - - } - - private static class TypeExpression implements Expression - { - public Object evaluate(Filterable message) - { - - String type = message.getMessageHeader().getType(); - return type; - - } - } - - private static class DeliveryModeExpression implements Expression - { - public Object evaluate(Filterable message) - { - JMSDeliveryMode mode = message.isPersistent() ? JMSDeliveryMode.PERSISTENT : - JMSDeliveryMode.NON_PERSISTENT; - if (_logger.isDebugEnabled()) - { - _logger.debug("JMSDeliveryMode is :" + mode); - } - - return mode.toString(); - } - } - - private static class PriorityExpression implements Expression - { - public Object evaluate(Filterable message) - { - byte priority = message.getMessageHeader().getPriority(); - return (int) priority; - } - } - - private static class MessageIDExpression implements Expression - { - public Object evaluate(Filterable message) - { - - String messageId = message.getMessageHeader().getMessageId(); - - return messageId; - - } - } - - private static class TimestampExpression implements Expression - { - public Object evaluate(Filterable message) - { - long timestamp = message.getMessageHeader().getTimestamp(); - return timestamp; - } - } - - private static class CorrelationIdExpression implements Expression - { - public Object evaluate(Filterable message) - { - - String correlationId = message.getMessageHeader().getCorrelationId(); - - return correlationId; - } - } - - private static class ExpirationExpression implements Expression - { - public Object evaluate(Filterable message) - { - long expiration = message.getMessageHeader().getExpiration(); - return expiration; - - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java index 360a5d45ce..b2a9009d23 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java @@ -20,12 +20,12 @@ */ package org.apache.qpid.server.filter; -import java.util.concurrent.ConcurrentLinkedQueue; - import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; + import org.apache.qpid.server.queue.Filterable; +import java.util.concurrent.ConcurrentLinkedQueue; + public class SimpleFilterManager implements FilterManager { private final Logger _logger = Logger.getLogger(SimpleFilterManager.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/UnaryExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/UnaryExpression.java deleted file mode 100644 index 557af95001..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/UnaryExpression.java +++ /dev/null @@ -1,362 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import java.math.BigDecimal; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.queue.Filterable; - -/** - * An expression which performs an operation on two expression values - */ -public abstract class UnaryExpression implements Expression -{ - - private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE); - protected Expression right; - - public static Expression createNegate(Expression left) - { - return new NegativeExpression(left); - } - - public static BooleanExpression createInExpression(PropertyExpression right, List elements, final boolean not) - { - - // Use a HashSet if there are many elements. - Collection t; - if (elements.size() == 0) - { - t = null; - } - else if (elements.size() < 5) - { - t = elements; - } - else - { - t = new HashSet(elements); - } - - final Collection inList = t; - - return new InExpression(right, inList, not); - } - - abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression - { - public BooleanUnaryExpression(Expression left) - { - super(left); - } - - public boolean matches(Filterable message) - { - Object object = evaluate(message); - - return (object != null) && (object == Boolean.TRUE); - } - } - ; - - public static<E extends Exception> BooleanExpression createNOT(BooleanExpression left) - { - return new NotExpression(left); - } - - public static BooleanExpression createXPath(final String xpath) - { - return new XPathExpression(xpath); - } - - public static BooleanExpression createXQuery(final String xpath) - { - return new XQueryExpression(xpath); - } - - public static<E extends Exception> BooleanExpression createBooleanCast(Expression left) - { - return new BooleanCastExpression(left); - } - - private static Number negate(Number left) - { - Class clazz = left.getClass(); - if (clazz == Integer.class) - { - return -left.intValue(); - } - else if (clazz == Long.class) - { - return -left.longValue(); - } - else if (clazz == Float.class) - { - return -left.floatValue(); - } - else if (clazz == Double.class) - { - return -left.doubleValue(); - } - else if (clazz == BigDecimal.class) - { - // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the - // Selector. Long.MIN_VALUE is too big to store in a Long as a positive so we store it - // as a Big decimal. But it gets Negated right away.. to here we try to covert it back - // to a Long. - BigDecimal bd = (BigDecimal) left; - bd = bd.negate(); - - if (BD_LONG_MIN_VALUE.compareTo(bd) == 0) - { - return Long.MIN_VALUE; - } - - return bd; - } - else - { - throw new RuntimeException("Don't know how to negate: " + left); - } - } - - public UnaryExpression(Expression left) - { - this.right = left; - } - - public Expression getRight() - { - return right; - } - - public void setRight(Expression expression) - { - right = expression; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() - { - return "(" + getExpressionSymbol() + " " + right.toString() + ")"; - } - - /** - * TODO: more efficient hashCode() - * - * @see java.lang.Object#hashCode() - */ - public int hashCode() - { - return toString().hashCode(); - } - - /** - * TODO: more efficient hashCode() - * - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object o) - { - return ((o != null) && this.getClass().equals(o.getClass())) && toString().equals(o.toString()); - } - - /** - * Returns the symbol that represents this binary expression. For example, addition is - * represented by "+" - * - * @return - */ - public abstract String getExpressionSymbol(); - - private static class NegativeExpression extends UnaryExpression - { - public NegativeExpression(final Expression left) - { - super(left); - } - - public Object evaluate(Filterable message) - { - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - if (rvalue instanceof Number) - { - return negate((Number) rvalue); - } - - return null; - } - - public String getExpressionSymbol() - { - return "-"; - } - } - - private static class InExpression extends BooleanUnaryExpression - { - private final Collection _inList; - private final boolean _not; - - public InExpression(final PropertyExpression right, final Collection inList, final boolean not) - { - super(right); - _inList = inList; - _not = not; - } - - public Object evaluate(Filterable message) - { - - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - if (rvalue.getClass() != String.class) - { - return null; - } - - if (((_inList != null) && _inList.contains(rvalue)) ^ _not) - { - return Boolean.TRUE; - } - else - { - return Boolean.FALSE; - } - - } - - public String toString() - { - StringBuffer answer = new StringBuffer(); - answer.append(right); - answer.append(" "); - answer.append(getExpressionSymbol()); - answer.append(" ( "); - - int count = 0; - for (Iterator i = _inList.iterator(); i.hasNext();) - { - Object o = (Object) i.next(); - if (count != 0) - { - answer.append(", "); - } - - answer.append(o); - count++; - } - - answer.append(" )"); - - return answer.toString(); - } - - public String getExpressionSymbol() - { - if (_not) - { - return "NOT IN"; - } - else - { - return "IN"; - } - } - } - - private static class NotExpression extends BooleanUnaryExpression - { - public NotExpression(final BooleanExpression left) - { - super(left); - } - - public Object evaluate(Filterable message) - { - Boolean lvalue = (Boolean) right.evaluate(message); - if (lvalue == null) - { - return null; - } - - return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE; - } - - public String getExpressionSymbol() - { - return "NOT"; - } - } - - private static class BooleanCastExpression extends BooleanUnaryExpression - { - public BooleanCastExpression(final Expression left) - { - super(left); - } - - public Object evaluate(Filterable message) - { - Object rvalue = right.evaluate(message); - if (rvalue == null) - { - return null; - } - - if (!rvalue.getClass().equals(Boolean.class)) - { - return Boolean.FALSE; - } - - return ((Boolean) rvalue).booleanValue() ? Boolean.TRUE : Boolean.FALSE; - } - - public String toString() - { - return right.toString(); - } - - public String getExpressionSymbol() - { - return ""; - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XPathExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XPathExpression.java deleted file mode 100644 index aa35cb5a76..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XPathExpression.java +++ /dev/null @@ -1,126 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.server.queue.Filterable; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -/** - * Used to evaluate an XPath Expression in a JMS selector. - */ -public final class XPathExpression implements BooleanExpression { - - private static final Logger log = Logger.getLogger(XPathExpression.class); - private static final String EVALUATOR_SYSTEM_PROPERTY = "org.apache.qpid.server.filter.XPathEvaluatorClassName"; - private static final String DEFAULT_EVALUATOR_CLASS_NAME=XalanXPathEvaluator.class.getName(); - - private static final Constructor EVALUATOR_CONSTRUCTOR; - - static { - String cn = System.getProperty(EVALUATOR_SYSTEM_PROPERTY, DEFAULT_EVALUATOR_CLASS_NAME); - Constructor m = null; - try { - try { - m = getXPathEvaluatorConstructor(cn); - } catch (Throwable e) { - log.warn("Invalid "+XPathEvaluator.class.getName()+" implementation: "+cn+", reason: "+e,e); - cn = DEFAULT_EVALUATOR_CLASS_NAME; - try { - m = getXPathEvaluatorConstructor(cn); - } catch (Throwable e2) { - log.error("Default XPath evaluator could not be loaded",e); - } - } - } finally { - EVALUATOR_CONSTRUCTOR = m; - } - } - - private static Constructor getXPathEvaluatorConstructor(String cn) throws ClassNotFoundException, SecurityException, NoSuchMethodException { - Class c = XPathExpression.class.getClassLoader().loadClass(cn); - if( !XPathEvaluator.class.isAssignableFrom(c) ) { - throw new ClassCastException(""+c+" is not an instance of "+XPathEvaluator.class); - } - return c.getConstructor(new Class[]{String.class}); - } - - private final String xpath; - private final XPathEvaluator evaluator; - - static public interface XPathEvaluator { - public boolean evaluate(Filterable message); - } - - XPathExpression(String xpath) { - this.xpath = xpath; - this.evaluator = createEvaluator(xpath); - } - - private XPathEvaluator createEvaluator(String xpath2) { - try { - return (XPathEvaluator)EVALUATOR_CONSTRUCTOR.newInstance(new Object[]{xpath}); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if( cause instanceof RuntimeException ) { - throw (RuntimeException)cause; - } - throw new RuntimeException("Invalid XPath Expression: "+xpath+" reason: "+e.getMessage(), e); - } catch (Throwable e) { - throw new RuntimeException("Invalid XPath Expression: "+xpath+" reason: "+e.getMessage(), e); - } - } - - public Object evaluate(Filterable message) { -// try { -//FIXME this is flow to disk work -// if( message.isDropped() ) -// return null; - return evaluator.evaluate(message) ? Boolean.TRUE : Boolean.FALSE; -// } catch (IOException e) { -// -// JMSException exception = new JMSException(e.getMessage()); -// exception.initCause(e); -// throw exception; -// -// } - - } - - public String toString() { - return "XPATH "+ConstantExpression.encodeString(xpath); - } - - /** - * @param message - * @return true if the expression evaluates to Boolean.TRUE. - * @throws AMQException - */ - public boolean matches(Filterable message) - { - Object object = evaluate(message); - return object!=null && object==Boolean.TRUE; - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XQueryExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XQueryExpression.java deleted file mode 100644 index ae22f17413..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XQueryExpression.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.filter; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.queue.Filterable; - -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -/** - * Used to evaluate an XQuery Expression in a JMS selector. - */ -public final class XQueryExpression implements BooleanExpression { - private final String xpath; - - XQueryExpression(String xpath) { - super(); - this.xpath = xpath; - } - - public Object evaluate(Filterable message) { - return Boolean.FALSE; - } - - public String toString() { - return "XQUERY "+ConstantExpression.encodeString(xpath); - } - - /** - * @param message - * @return true if the expression evaluates to Boolean.TRUE. - * @throws AMQException - */ - public boolean matches(Filterable message) - { - Object object = evaluate(message); - return object!=null && object==Boolean.TRUE; - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XalanXPathEvaluator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XalanXPathEvaluator.java deleted file mode 100644 index f83eb63ac5..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/XalanXPathEvaluator.java +++ /dev/null @@ -1,101 +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.filter; -// -// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html> -// - -import java.io.ByteArrayInputStream; -import java.io.StringReader; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.apache.qpid.server.queue.Filterable; -import org.apache.xpath.CachedXPathAPI; -import org.w3c.dom.Document; -import org.w3c.dom.traversal.NodeIterator; -import org.xml.sax.InputSource; - -public class XalanXPathEvaluator implements XPathExpression.XPathEvaluator { - - private final String xpath; - - public XalanXPathEvaluator(String xpath) { - this.xpath = xpath; - } - - public boolean evaluate(Filterable m) - { - // TODO - we would have to check the content type and then evaluate the content - // here... is this really a feature we wish to implement? - RobG - /* - - if( m instanceof TextMessage ) { - String text = ((TextMessage)m).getText(); - return evaluate(text); - } else if ( m instanceof BytesMessage ) { - BytesMessage bm = (BytesMessage) m; - byte data[] = new byte[(int) bm.getBodyLength()]; - bm.readBytes(data); - return evaluate(data); - } - */ - return false; - - } - - private boolean evaluate(byte[] data) { - try { - - InputSource inputSource = new InputSource(new ByteArrayInputStream(data)); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - DocumentBuilder dbuilder = factory.newDocumentBuilder(); - Document doc = dbuilder.parse(inputSource); - - CachedXPathAPI cachedXPathAPI = new CachedXPathAPI(); - NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc,xpath); - return iterator.nextNode()!=null; - - } catch (Throwable e) { - return false; - } - } - - private boolean evaluate(String text) { - try { - InputSource inputSource = new InputSource(new StringReader(text)); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - DocumentBuilder dbuilder = factory.newDocumentBuilder(); - Document doc = dbuilder.parse(inputSource); - - // We should associated the cachedXPathAPI object with the message being evaluated - // since that should speedup subsequent xpath expressions. - CachedXPathAPI cachedXPathAPI = new CachedXPathAPI(); - NodeIterator iterator = cachedXPathAPI.selectNodeIterator(doc,xpath); - return iterator.nextNode()!=null; - } catch (Throwable e) { - return false; - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java index a77ed5700a..124fb0d1d9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/AbstractFlowCreditManager.java @@ -22,12 +22,10 @@ package org.apache.qpid.server.flow; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.Set; -import java.util.HashSet; public abstract class AbstractFlowCreditManager implements FlowCreditManager { - protected final AtomicBoolean _suspended = new AtomicBoolean(false); + private final AtomicBoolean _suspended = new AtomicBoolean(false); private final ArrayList<FlowCreditManagerListener> _listeners = new ArrayList<FlowCreditManagerListener>(); public final void addStateListener(FlowCreditManagerListener listener) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/CreditCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/CreditCreditManager.java index c6771177ac..09fe44338c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/CreditCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/CreditCreditManager.java @@ -23,14 +23,8 @@ package org.apache.qpid.server.flow; public class CreditCreditManager extends AbstractFlowCreditManager implements FlowCreditManager_0_10 { - private volatile long _bytesCredit; - private volatile long _messageCredit; - - - public CreditCreditManager() - { - this(0L, 0L); - } + private volatile long _bytesCredit; + private volatile long _messageCredit; public CreditCreditManager(long bytesCredit, long messageCredit) { @@ -67,9 +61,6 @@ public class CreditCreditManager extends AbstractFlowCreditManager implements Fl public synchronized void restoreCredit(final long messageCredit, final long bytesCredit) { - /*_bytesCredit = 0l; - _messageCredit = 0l; - setSuspended(true);*/ } @@ -138,7 +129,6 @@ public class CreditCreditManager extends AbstractFlowCreditManager implements Fl } else { - //setSuspended(true); return false; } } @@ -158,7 +148,6 @@ public class CreditCreditManager extends AbstractFlowCreditManager implements Fl } else { - //setSuspended(true); return false; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java index a193f8fae4..fc2d4bfb53 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java @@ -155,7 +155,6 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F } else { - //setSuspended(true); return false; } } @@ -183,7 +182,6 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F } else { - //setSuspended(true); return false; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/WindowCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/WindowCreditManager.java index a0c2e9f977..2215c7bb3d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/WindowCreditManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/WindowCreditManager.java @@ -144,7 +144,6 @@ public class WindowCreditManager extends AbstractFlowCreditManager implements Fl } else { - //setSuspended(true); return false; } } @@ -164,7 +163,6 @@ public class WindowCreditManager extends AbstractFlowCreditManager implements Fl } else { - //setSuspended(true); return false; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java index 1b0168df56..e1c2782dec 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java @@ -21,15 +21,17 @@ package org.apache.qpid.server.handler; */
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AccessRequestBody;
+import org.apache.qpid.framing.AccessRequestOkBody;
+import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9;
+import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.state.StateAwareMethodListener;
-import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.server.state.StateAwareMethodListener;
/**
* @author Apache Software Foundation
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java index f90e7c3dff..398a3ff58a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicAckBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java index bc2a2dca04..0741385d42 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.server.handler; +import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicCancelBody; import org.apache.qpid.framing.BasicCancelOkBody; @@ -28,7 +30,6 @@ import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.log4j.Logger; public class BasicCancelMethodHandler implements StateAwareMethodListener<BasicCancelBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java index a1cfb14753..514829625d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java @@ -21,8 +21,12 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicConsumeBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java index 2073299467..191643493e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java @@ -22,28 +22,26 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicGetBody; import org.apache.qpid.framing.BasicGetEmptyBody; import org.apache.qpid.framing.MethodRegistry; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.flow.FlowCreditManager; import org.apache.qpid.server.flow.MessageOnlyCreditManager; -import org.apache.qpid.server.subscription.SubscriptionImpl; -import org.apache.qpid.server.subscription.ClientDeliveryMethod; -import org.apache.qpid.server.subscription.RecordDeliveryMethod; -import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; +import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; +import org.apache.qpid.server.subscription.ClientDeliveryMethod; +import org.apache.qpid.server.subscription.RecordDeliveryMethod; +import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.virtualhost.VirtualHost; public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetBody> diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java index 8f23b1c4d4..cb8918e847 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java index 2cf043dd26..87a3d1c210 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java @@ -21,13 +21,13 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.BasicQosBody; import org.apache.qpid.framing.MethodRegistry; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.qpid.server.AMQChannel; public class BasicQosHandler implements StateAwareMethodListener<BasicQosBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java index 429217321c..0c4c9cac47 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java @@ -21,13 +21,12 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.BasicRecoverBody; -import org.apache.qpid.framing.BasicRecoverOkBody; import org.apache.qpid.framing.ProtocolVersion; -import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java index 1e2a83b922..1e0c0273df 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java @@ -23,18 +23,16 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger;
-import org.apache.qpid.framing.BasicRecoverBody;
-import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.BasicRecoverSyncBody;
-import org.apache.qpid.framing.amqp_0_91.MethodRegistry_0_91;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9;
-import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0;
-import org.apache.qpid.server.state.StateAwareMethodListener;
-import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.framing.amqp_0_91.MethodRegistry_0_91;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.server.state.StateAwareMethodListener;
public class BasicRecoverSyncMethodHandler implements StateAwareMethodListener<BasicRecoverSyncBody>
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java index 0ea88e4ab6..de76050898 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java @@ -20,14 +20,15 @@ */ package org.apache.qpid.server.handler; +import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicRejectBody; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.log4j.Logger; public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicRejectBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java index ecffd1b9cb..0c8ab318b2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java @@ -21,17 +21,16 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.ChannelCloseBody; import org.apache.qpid.framing.ChannelCloseOkBody; import org.apache.qpid.framing.MethodRegistry; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.qpid.server.AMQChannel; public class ChannelCloseHandler implements StateAwareMethodListener<ChannelCloseBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java index a857490e7e..54b3f813af 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java index 365c8bd9c6..a736ad5fb0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java @@ -21,9 +21,11 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; -import org.apache.qpid.framing.*; -import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.ChannelFlowBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java index 6d874ee971..81734d7825 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java @@ -20,12 +20,8 @@ */ package org.apache.qpid.server.handler; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.UUID; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.ChannelOpenBody; import org.apache.qpid.framing.ChannelOpenOkBody; @@ -41,6 +37,11 @@ import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.UUID; + public class ChannelOpenHandler implements StateAwareMethodListener<ChannelOpenBody> { private static final Logger _logger = Logger.getLogger(ChannelOpenHandler.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java index 6eaba87b79..7f0c0d2974 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java @@ -21,12 +21,11 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionCloseOkBody; import org.apache.qpid.framing.MethodRegistry; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java index bc6e5ab403..bd86c2d3f1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java index 9a79467526..79fcfb6d76 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.AMQShortString; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java index 09f35da41d..2ccf97f17c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java @@ -21,9 +21,8 @@ package org.apache.qpid.server.handler; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionSecureBody; @@ -40,6 +39,9 @@ import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener<ConnectionSecureOkBody> { private static final Logger _logger = Logger.getLogger(ConnectionSecureOkMethodHandler.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java index 2dd9a63540..162e4e0215 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java @@ -20,10 +20,8 @@ */ package org.apache.qpid.server.handler; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionSecureBody; @@ -41,6 +39,9 @@ import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<ConnectionStartOkBody> { @@ -79,10 +80,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); //save clientProperties - if (session.getClientProperties() == null) - { - session.setClientProperties(body.getClientProperties()); - } + session.setClientProperties(body.getClientProperties()); MethodRegistry methodRegistry = session.getMethodRegistry(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java index 1da2760639..299aad0fe7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.ConnectionTuneOkBody; import org.apache.qpid.server.protocol.AMQProtocolSession; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java index 53835f381f..b4eb41684d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java @@ -21,12 +21,15 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ExchangeBoundBody; +import org.apache.qpid.framing.ExchangeBoundOkBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.virtualhost.VirtualHost; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java index 69cf0c9e20..6d55f31ebc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java @@ -21,10 +21,14 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQConnectionException; import org.apache.qpid.AMQException; import org.apache.qpid.AMQUnknownExchangeType; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ExchangeDeclareBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.exchange.Exchange; @@ -62,26 +66,39 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange throw body.getChannelNotFoundException(channelId); } + final AMQShortString exchangeName = body.getExchange(); if (_logger.isDebugEnabled()) { - _logger.debug("Request to declare exchange of type " + body.getType() + " with name " + body.getExchange()); + _logger.debug("Request to declare exchange of type " + body.getType() + " with name " + exchangeName); } synchronized(exchangeRegistry) { - Exchange exchange = exchangeRegistry.getExchange(body.getExchange()); + Exchange exchange = exchangeRegistry.getExchange(exchangeName); if (exchange == null) { if(body.getPassive() && ((body.getType() == null) || body.getType().length() ==0)) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Unknown exchange: " + body.getExchange()); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Unknown exchange: " + exchangeName); + } + else if(exchangeName.startsWith("amq.")) + { + throw body.getConnectionException(AMQConstant.NOT_ALLOWED, + "Attempt to declare exchange: " + exchangeName + + " which begins with reserved prefix 'amq.'."); + } + else if(exchangeName.startsWith("qpid.")) + { + throw body.getConnectionException(AMQConstant.NOT_ALLOWED, + "Attempt to declare exchange: " + exchangeName + + " which begins with reserved prefix 'qpid.'."); } else { try { - exchange = exchangeFactory.createExchange(body.getExchange() == null ? null : body.getExchange().intern(), + exchange = exchangeFactory.createExchange(exchangeName == null ? null : exchangeName.intern(), body.getType() == null ? null : body.getType().intern(), body.getDurable(), body.getPassive(), body.getTicket()); @@ -94,14 +111,15 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange } catch(AMQUnknownExchangeType e) { - throw body.getConnectionException(AMQConstant.COMMAND_INVALID, "Unknown exchange: " + body.getExchange(),e); + throw body.getConnectionException(AMQConstant.COMMAND_INVALID, "Unknown exchange: " + exchangeName,e); } } } - else if (!exchange.getTypeShortString().equals(body.getType())) + else if (!exchange.getTypeShortString().equals(body.getType()) && !((body.getType() == null || body.getType().length() ==0) && body.getPassive())) { - throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getTypeShortString() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor(),null); + throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + + exchangeName + " of type " + exchange.getTypeShortString() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor(),null); } } if(!body.getNowait()) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index 32cd1c2d08..f57f7eb9e6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -20,11 +20,8 @@ */ package org.apache.qpid.server.handler; -import java.util.UUID; -import java.util.Collections; -import java.util.concurrent.atomic.AtomicInteger; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.MethodRegistry; @@ -45,6 +42,9 @@ import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Collections; +import java.util.UUID; + public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclareBody> { private static final Logger _logger = Logger.getLogger(QueueDeclareHandler.class); @@ -56,9 +56,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar return _instance; } - public boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); - - private final AtomicInteger _counter = new AtomicInteger(); + private boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java index 107e485275..cc37259d54 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java @@ -21,19 +21,19 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.QueueDeleteBody; import org.apache.qpid.framing.QueueDeleteOkBody; -import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.AMQChannel; public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java index 7d609f9064..217a264793 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java @@ -22,18 +22,18 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.QueuePurgeBody; -import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.QueuePurgeBody; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.AMQChannel; public class QueuePurgeHandler implements StateAwareMethodListener<QueuePurgeBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java index 9915627a94..a8ae2099cc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.handler; */ import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.AMQShortString; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java index e290afcde3..3b6dc3f3f5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java @@ -20,12 +20,12 @@ */
package org.apache.qpid.server.handler;
-import java.util.Map;
-import java.util.HashMap;
-
-import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.framing.*;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.server.state.AMQStateManager;
+
+import java.util.HashMap;
+import java.util.Map;
public class ServerMethodDispatcherImpl implements MethodDispatcher
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java index 8b1dca77ba..7ce8664d37 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.handler;
-import org.apache.qpid.framing.amqp_0_9.MethodDispatcher_0_9;
+import org.apache.qpid.AMQException;
import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.amqp_0_9.MethodDispatcher_0_9;
import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.AMQException;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_91.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_91.java index 32cd4c4e9f..126e1484b6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_91.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_91.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.handler;
+import org.apache.qpid.AMQException;
import org.apache.qpid.framing.*;
import org.apache.qpid.framing.amqp_0_91.MethodDispatcher_0_91;
import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.AMQException;
public class ServerMethodDispatcherImpl_0_91
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java index d599ca3d4e..fabd2a5ccf 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java @@ -20,10 +20,19 @@ */
package org.apache.qpid.server.handler;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.BasicRecoverOkBody;
+import org.apache.qpid.framing.ChannelAlertBody;
+import org.apache.qpid.framing.TestContentBody;
+import org.apache.qpid.framing.TestContentOkBody;
+import org.apache.qpid.framing.TestIntegerBody;
+import org.apache.qpid.framing.TestIntegerOkBody;
+import org.apache.qpid.framing.TestStringBody;
+import org.apache.qpid.framing.TestStringOkBody;
+import org.apache.qpid.framing.TestTableBody;
+import org.apache.qpid.framing.TestTableOkBody;
import org.apache.qpid.framing.amqp_8_0.MethodDispatcher_8_0;
-import org.apache.qpid.framing.*;
import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.AMQException;
public class ServerMethodDispatcherImpl_8_0
extends ServerMethodDispatcherImpl
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java index abd2bccc8d..6e8896a023 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java @@ -21,10 +21,11 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; -import org.apache.qpid.framing.TxCommitBody; -import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.TxCommitBody; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java index 20ba3af458..010a07be14 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java @@ -21,11 +21,9 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.TxRollbackBody; -import org.apache.qpid.framing.TxRollbackOkBody; -import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.TxRollbackBody; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java index 308f5b73cf..44b47704d8 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java @@ -21,14 +21,13 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.TxSelectBody; import org.apache.qpid.framing.TxSelectOkBody; -import org.apache.qpid.framing.MethodRegistry; -import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -import org.apache.qpid.server.AMQChannel; public class TxSelectHandler implements StateAwareMethodListener<TxSelectBody> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java index 3526fdcae5..cfc52c558c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java @@ -21,8 +21,8 @@ package org.apache.qpid.server.handler;
-import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQMethodBody;
public class UnexpectedMethodException extends AMQException
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java index 5e6a143d52..4d395f625a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.server.information.management; -import java.io.IOException; - import org.apache.qpid.common.QpidProperties; import org.apache.qpid.management.common.mbeans.ServerInformation; import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; @@ -29,6 +27,7 @@ import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.registry.ApplicationRegistry; import javax.management.JMException; +import java.io.IOException; /** MBean class for the ServerInformationMBean. */ @MBeanDescription("Server Information Interface") diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java index a0285ebfc4..ec506ab51c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java @@ -22,6 +22,7 @@ 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 diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java index 9c7ffcc5f8..50a7e67583 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AMQPChannelActor.java @@ -23,9 +23,6 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.logging.subjects.ChannelLogSubject; -import org.apache.qpid.server.protocol.AMQProtocolSession; - -import java.text.MessageFormat; /** * An AMQPChannelActor represtents a connection through the AMQP port with an diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java index e0bf180cc4..e8c6c9c323 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractActor.java @@ -27,9 +27,9 @@ import org.apache.qpid.server.logging.RootMessageLogger; public abstract class AbstractActor implements LogActor { - public final String _msgPrefix = System.getProperty("qpid.logging.prefix",""); + private final String _msgPrefix = System.getProperty("qpid.logging.prefix",""); - protected RootMessageLogger _rootLogger; + private RootMessageLogger _rootLogger; public AbstractActor(RootMessageLogger rootLogger) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java index 2ebbfeb734..feacf35d41 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java @@ -68,6 +68,10 @@ public class CurrentActor private static LogActor _defaultActor; + private CurrentActor() + { + } + /** * Set a new {@link LogActor} to be the Current Actor * <p/> diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java index 9afc76ce78..0e418a95e2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/GenericActor.java @@ -24,7 +24,6 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.RootMessageLogger; -import org.apache.qpid.server.registry.ApplicationRegistry; public class GenericActor extends AbstractActor { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java index 286fc78719..9cd3c66629 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java @@ -22,14 +22,13 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.logging.RootMessageLogger; +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; -import javax.management.remote.JMXPrincipal; -import javax.security.auth.Subject; - /** * NOTE: This actor is not thread safe. * @@ -52,7 +51,7 @@ public class ManagementActor extends AbstractActor */ private static final String UNKNOWN_PRINCIPAL = "N/A"; - String _lastThreadName = null; + private String _lastThreadName = null; /** * LOG FORMAT for the ManagementActor, diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java index 3364365b61..4b17e8c0e6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/actors/QueueActor.java @@ -24,8 +24,6 @@ import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.logging.subjects.QueueLogSubject; import org.apache.qpid.server.queue.AMQQueue; -import java.text.MessageFormat; - /** * This Actor is used when while the queue is performing an asynchronous process * of its queue. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java index a823fb7cb1..c699dff175 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java @@ -20,35 +20,22 @@ */ package org.apache.qpid.server.logging.management; -import static org.apache.log4j.xml.QpidLog4JConfigurator.LOCK; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.apache.qpid.management.common.mbeans.LoggingManagement; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; -import org.apache.qpid.server.management.AMQManagedObject; -import org.apache.qpid.util.FileUtils; - import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.xml.Log4jEntityResolver; import org.apache.log4j.xml.QpidLog4JConfigurator; -import org.apache.log4j.xml.QpidLog4JConfigurator.QpidLog4JSaxErrorHandler; import org.apache.log4j.xml.QpidLog4JConfigurator.IllegalLoggerLevelException; +import org.apache.log4j.xml.QpidLog4JConfigurator.QpidLog4JSaxErrorHandler; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; + +import org.apache.qpid.management.common.mbeans.LoggingManagement; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; +import org.apache.qpid.server.management.AMQManagedObject; import javax.management.JMException; import javax.management.openmbean.CompositeData; @@ -69,6 +56,16 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import static org.apache.log4j.xml.QpidLog4JConfigurator.LOCK; /** MBean class for BrokerLoggingManagerMBean. It implements all the management features exposed for managing logging. */ @@ -85,8 +82,8 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM Level.WARN.toString(), Level.ERROR.toString(), Level.FATAL.toString(),Level.OFF.toString(), INHERITED}; - static TabularType _loggerLevelTabularType; - static CompositeType _loggerLevelCompositeType; + private static TabularType _loggerLevelTabularType; + private static CompositeType _loggerLevelCompositeType; static { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties index 5d1e85fe41..1aa7815c39 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties @@ -26,7 +26,7 @@ STARTUP = BRK-1001 : Startup : Version: {0} Build: {1} LISTENING = BRK-1002 : Starting : Listening on {0} port {1,number,#} # 0 - Transport # 1 - Port -SHUTTING_DOWN = BRK-1003 : Shuting down : {0} port {1,number,#} +SHUTTING_DOWN = BRK-1003 : Shutting down : {0} port {1,number,#} READY = BRK-1004 : Qpid Broker Ready STOPPED = BRK-1005 : Stopped # 0 - path @@ -35,4 +35,14 @@ CONFIG = BRK-1006 : Using configuration : {0} LOG_CONFIG = BRK-1007 : Using logging configuration : {0} STATS_DATA = BRK-1008 : {0,choice,0#delivered|1#received} : {1,number,#.###} kB/s peak : {2,number,#} bytes total -STATS_MSGS = BRK-1009 : {0,choice,0#delivered|1#received} : {1,number,#.###} msg/s peak : {2,number,#} msgs total
\ No newline at end of file +STATS_MSGS = BRK-1009 : {0,choice,0#delivered|1#received} : {1,number,#.###} msg/s peak : {2,number,#} msgs total + +# 0 - java vendor +# 1 - java runtime version +# 2 - os name +# 3 - os type +# 4 - os architecture +PLATFORM = BRK-1010 : Platform : JVM : {0} version: {1} OS : {2} version: {3} arch: {4} + +# 0 Maximum Memory +MAX_MEMORY = BRK-1011 : Maximum Memory : {0,number} bytes
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties index 81ae6f3bd0..8559862a45 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Connection_logmessages.properties @@ -20,5 +20,6 @@ # 0 - Client id # 1 - Protocol Version -OPEN = CON-1001 : Open[ : Client ID : {0}][ : Protocol Version : {1}] +# 2 - Client Version +OPEN = CON-1001 : Open[ : Client ID : {0}][ : Protocol Version : {1}][ : Client Version : {2}] CLOSE = CON-1002 : Close
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties index fadc2e2098..9ef58df940 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/TransactionLog_logmessages.properties @@ -31,3 +31,9 @@ RECOVERY_START = TXN-1004 : Recovery Start[ : {0}] RECOVERED = TXN-1005 : Recovered {0,number} messages for queue {1} # 0 - queue name RECOVERY_COMPLETE = TXN-1006 : Recovery Complete[ : {0}] +# 0 - xid +# 1 - queue name +XA_INCOMPLETE_QUEUE = TXN-1007 : XA transaction recover for xid {0} incomplete as it references a queue {1} which was not durably retained +# 0 - xid format +# 1 - message id +XA_INCOMPLETE_MESSAGE = TXN-1008 : XA transaction recover for xid {0} incomplete as it references a message {1} which was not durably retained diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java index 779db01601..baccf240ff 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/AbstractLogSubject.java @@ -33,10 +33,7 @@ import java.text.MessageFormat; */ public abstract class AbstractLogSubject implements LogSubject { - /** - * The logString that will be returned via toLogString - */ - protected String _logString; + private String _logString; /** * Set the toString logging of this LogSubject. Based on a format provided @@ -60,4 +57,16 @@ public abstract class AbstractLogSubject implements LogSubject return _logString; } + /** + * The logString that will be returned via toLogString + */ + public String getLogString() + { + return _logString; + } + + public void setLogString(String logString) + { + _logString = logString; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java index 088b59ae68..8f0b9182a9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/BindingLogSubject.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.queue.AMQQueue; + import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.BINDING_FORMAT; public class BindingLogSubject extends AbstractLogSubject diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java index 885b039e18..859d7e2a27 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java @@ -36,8 +36,7 @@ public class ChannelLogSubject extends AbstractLogSubject /** * LOG FORMAT used by the AMQPConnectorActor follows - * ChannelLogSubject.CHANNEL_FORMAT : - * con:{0}({1}@{2}/{3})/ch:{4} + * ChannelLogSubject.CHANNEL_FORMAT : con:{0}({1}@{2}/{3})/ch:{4}. * * Uses a MessageFormat call to insert the required values according to * these indices: @@ -60,8 +59,7 @@ public class ChannelLogSubject extends AbstractLogSubject { /** * LOG FORMAT used by the AMQPConnectorActor follows - * ChannelLogSubject.CHANNEL_FORMAT : - * con:{0}({1}@{2}/{3})/ch:{4} + * ChannelLogSubject.CHANNEL_FORMAT : con:{0}({1}@{2}/{3})/ch:{4}. * * Uses a MessageFormat call to insert the required values according to * these indices: diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java index c1c836f9b4..3b08a172b6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java @@ -22,11 +22,11 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.protocol.AMQProtocolSession; -import java.text.MessageFormat; - +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORMAT; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT; + +import java.text.MessageFormat; /** The Connection LogSubject */ public class ConnectionLogSubject extends AbstractLogSubject @@ -70,31 +70,31 @@ public class ConnectionLogSubject extends AbstractLogSubject * * 0 - Connection ID 1 - User ID 2 - IP 3 - Virtualhost */ - _logString = "[" + MessageFormat.format(CONNECTION_FORMAT, - _session.getSessionID(), - _session.getAuthorizedPrincipal().getName(), + setLogString("[" + MessageFormat.format(CONNECTION_FORMAT, + _session.getSessionID(), + _session.getAuthorizedPrincipal().getName(), _session.getRemoteAddress(), - _session.getVirtualHost().getName()) - + "] "; + _session.getVirtualHost().getName()) + + "] "); _upToDate = true; } else { - _logString = "[" + MessageFormat.format(USER_FORMAT, - _session.getSessionID(), - _session.getAuthorizedPrincipal().getName(), + setLogString("[" + MessageFormat.format(USER_FORMAT, + _session.getSessionID(), + _session.getAuthorizedPrincipal().getName(), _session.getRemoteAddress()) - + "] "; + + "] "); } } else { - _logString = "[" + MessageFormat.format(SOCKET_FORMAT, + setLogString("[" + MessageFormat.format(SOCKET_FORMAT, _session.getSessionID(), - _session.getRemoteAddress()) - + "] "; + _session.getRemoteAddress()) + + "] "); } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java index 6ab44a92b9..99a54cc6d0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ExchangeLogSubject.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.virtualhost.VirtualHost; + import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.EXCHANGE_FORMAT; public class ExchangeLogSubject extends AbstractLogSubject diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java index ff2bb90140..28c4f0d52a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java @@ -32,7 +32,10 @@ package org.apache.qpid.server.logging.subjects; public class LogSubjectFormat { - + private LogSubjectFormat() + { + } + /** * LOG FORMAT for the Subscription Log Subject * 0 - Subscription ID diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java index 3fce13bcb5..969288be00 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/MessageStoreLogSubject.java @@ -20,8 +20,9 @@ */ package org.apache.qpid.server.logging.subjects; -import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.virtualhost.VirtualHost; + import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.STORE_FORMAT; public class MessageStoreLogSubject extends AbstractLogSubject diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java index bfe12f1a60..53a9ab75d9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/QueueLogSubject.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.queue.AMQQueue; + import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.QUEUE_FORMAT; public class QueueLogSubject extends AbstractLogSubject diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java index 8b57647046..9a23b733dc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/SubscriptionLogSubject.java @@ -22,10 +22,10 @@ package org.apache.qpid.server.logging.subjects; import org.apache.qpid.server.subscription.Subscription; -import java.text.MessageFormat; - import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SUBSCRIPTION_FORMAT; +import java.text.MessageFormat; + public class SubscriptionLogSubject extends AbstractLogSubject { @@ -42,14 +42,14 @@ public class SubscriptionLogSubject extends AbstractLogSubject String queueString = new QueueLogSubject(subscription.getQueue()).toLogString(); - _logString = "[" + MessageFormat.format(SUBSCRIPTION_FORMAT, + setLogString("[" + MessageFormat.format(SUBSCRIPTION_FORMAT, subscription.getSubscriptionID()) + "(" // queueString is [vh(/{0})/qu({1}) ] so need to trim // ^ ^^ + queueString.substring(1,queueString.length() - 3) + ")" - + "] "; + + "] "); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java index 6c9d6e39de..5c57c01f6e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java @@ -20,13 +20,11 @@ */ package org.apache.qpid.server.management; -import org.apache.qpid.server.logging.actors.ManagementActor; -import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.ManagementActor; import javax.management.ListenerNotFoundException; -import javax.management.MBeanInfo; -import javax.management.MBeanNotificationInfo; import javax.management.NotCompliantMBeanException; import javax.management.NotificationBroadcaster; import javax.management.NotificationBroadcasterSupport; @@ -42,17 +40,11 @@ import javax.management.NotificationListener; public abstract class AMQManagedObject extends DefaultManagedObject implements NotificationBroadcaster { - /** - * broadcaster support class - */ - protected NotificationBroadcasterSupport _broadcaster = new NotificationBroadcasterSupport(); + private NotificationBroadcasterSupport _broadcaster = new NotificationBroadcasterSupport(); - /** - * sequence number for notifications - */ - protected long _notificationSequenceNumber = 0; + private long _notificationSequenceNumber = 0; - protected LogActor _logActor; + private LogActor _logActor; protected AMQManagedObject(Class<?> managementInterface, String typeName) throws NotCompliantMBeanException @@ -79,4 +71,35 @@ public abstract class AMQManagedObject extends DefaultManagedObject } + /** + * broadcaster support class + */ + protected NotificationBroadcasterSupport getBroadcaster() + { + return _broadcaster; + } + + /** + * sequence number for notifications + */ + protected long getNotificationSequenceNumber() + { + return _notificationSequenceNumber; + } + + protected void setNotificationSequenceNumber(long notificationSequenceNumber) + { + _notificationSequenceNumber = notificationSequenceNumber; + } + + protected long incrementAndGetSequenceNumber() + { + return ++_notificationSequenceNumber; + } + + protected LogActor getLogActor() + { + return _logActor; + } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java index 68350a1632..e7c07b6dd4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AbstractAMQManagedConnectionObject.java @@ -1,21 +1,21 @@ package org.apache.qpid.server.management; -import javax.management.Notification; +import org.apache.qpid.management.common.mbeans.ManagedConnection; import javax.management.JMException; import javax.management.MBeanNotificationInfo; import javax.management.NotCompliantMBeanException; +import javax.management.Notification; import javax.management.ObjectName; import javax.management.monitor.MonitorNotification; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularType; -import org.apache.qpid.management.common.mbeans.ManagedConnection; public abstract class AbstractAMQManagedConnectionObject extends AMQManagedObject implements ManagedConnection { - protected final String _name; + private final String _name; protected static final OpenType[] _channelAttributeTypes = { SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.INTEGER, SimpleType.BOOLEAN }; protected static final CompositeType _channelType; @@ -45,7 +45,6 @@ public abstract class AbstractAMQManagedConnectionObject extends AMQManagedObjec _name = "anonymous".equals(remoteAddress) ? (remoteAddress + hashCode()) : remoteAddress; } - @Override public String getObjectInstanceName() { return ObjectName.quote(_name); @@ -53,9 +52,9 @@ public abstract class AbstractAMQManagedConnectionObject extends AMQManagedObjec public void notifyClients(String notificationMsg) { - final Notification n = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, ++_notificationSequenceNumber, + final Notification n = new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, incrementAndGetSequenceNumber(), System.currentTimeMillis(), notificationMsg); - _broadcaster.sendNotification(n); + getBroadcaster().sendNotification(n); } @Override diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java index 0c3a5fc571..10d7503800 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java @@ -20,6 +20,10 @@ */ package org.apache.qpid.server.management; +import org.apache.log4j.Logger; + +import org.apache.qpid.server.registry.ApplicationRegistry; + import javax.management.JMException; import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; @@ -28,9 +32,6 @@ import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import javax.management.StandardMBean; -import org.apache.log4j.Logger; -import org.apache.qpid.server.registry.ApplicationRegistry; - /** * Provides implementation of the boilerplate ManagedObject interface. Most managed objects should find it useful * to extend this class rather than implementing ManagedObject from scratch. @@ -153,7 +154,9 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana return parentType + "." + obj.getType(); } else + { return obj.getType(); + } } protected String getHierarchicalName(ManagedObject obj) @@ -167,7 +170,9 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana return parentName; } else + { return ""; + } } private MBeanInfo buildMBeanInfo() throws NotCompliantMBeanException diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java index 8583e8d57b..04a5b27991 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java @@ -20,6 +20,35 @@ */ package org.apache.qpid.server.management; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.log4j.Logger; + +import org.apache.qpid.AMQException; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator; +import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; + +import javax.management.JMException; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.Notification; +import javax.management.NotificationFilterSupport; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.remote.JMXConnectionNotification; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.MBeanServerForwarder; +import javax.management.remote.rmi.RMIConnection; +import javax.management.remote.rmi.RMIConnectorServer; +import javax.management.remote.rmi.RMIJRMPServerImpl; +import javax.management.remote.rmi.RMIServerImpl; +import javax.rmi.ssl.SslRMIClientSocketFactory; +import javax.rmi.ssl.SslRMIServerSocketFactory; +import javax.security.auth.Subject; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -41,35 +70,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javax.management.JMException; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.Notification; -import javax.management.NotificationFilterSupport; -import javax.management.NotificationListener; -import javax.management.ObjectName; -import javax.management.remote.JMXConnectionNotification; -import javax.management.remote.JMXConnectorServer; -import javax.management.remote.JMXServiceURL; -import javax.management.remote.MBeanServerForwarder; -import javax.management.remote.rmi.RMIConnection; -import javax.management.remote.rmi.RMIConnectorServer; -import javax.management.remote.rmi.RMIJRMPServerImpl; -import javax.management.remote.rmi.RMIServerImpl; -import javax.rmi.ssl.SslRMIClientSocketFactory; -import javax.rmi.ssl.SslRMIServerSocketFactory; -import javax.security.auth.Subject; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; - /** * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no * security features implemented like user authentication and authorisation. @@ -157,9 +157,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry if (!ksf.exists()) { - throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf + "\n" - + "Check broker configuration, or see create-example-ssl-stores script" - + "in the bin/ directory if you need to generate an example store."); + throw new FileNotFoundException("Cannot find JMX management SSL keystore file: " + ksf); } if (!ksf.canRead()) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java index 17a6851abc..89b74f939d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanIntrospector.java @@ -20,23 +20,22 @@ */ package org.apache.qpid.server.management; -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; +import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; +import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; import javax.management.MBeanAttributeInfo; import javax.management.MBeanConstructorInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.NotCompliantMBeanException; - -import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute; -import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; -import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; -import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; /** * This class is a utility class to introspect the MBean class and the management @@ -51,6 +50,10 @@ class MBeanIntrospector { private static final String _defaultConstructorDescription = "MBean constructor"; private static final String _defaultMbeanDescription = "Management interface of the MBean"; + private MBeanIntrospector() + { + } + /** * Introspects the management interface class for MBean attributes. * @param interfaceClass @@ -328,7 +331,9 @@ class MBeanIntrospector { paramInfo = new MBeanParameterInfo("p " + (i + 1), type, "parameter " + (i + 1)); } if (paramInfo != null) + { paramsInfo[i] = paramInfo; + } } return paramsInfo; @@ -346,9 +351,10 @@ class MBeanIntrospector { for (Constructor cons : implClass.getConstructors()) { MBeanConstructorInfo constructorInfo = getMBeanConstructorInfo(cons); - //MBeanConstructorInfo constructorInfo = new MBeanConstructorInfo("desc", cons); if (constructorInfo != null) + { constructors.add(constructorInfo); + } } return constructors.toArray(new MBeanConstructorInfo[0]); @@ -372,9 +378,6 @@ class MBeanIntrospector { } } - //MBeanParameterInfo[] paramsInfo = getParametersInfo(cons.getParameterAnnotations(), - // cons.getParameterTypes()); - return new MBeanConstructorInfo(cons.getName(), desc, null); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java index 40a221e0ba..651372db16 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java @@ -20,14 +20,14 @@ */ package org.apache.qpid.server.management; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.util.Map; -import java.util.Set; +import org.apache.log4j.Logger; + +import org.apache.qpid.server.logging.actors.ManagementActor; +import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.access.Operation; import javax.management.Attribute; import javax.management.JMException; @@ -41,14 +41,14 @@ import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXPrincipal; import javax.management.remote.MBeanServerForwarder; import javax.security.auth.Subject; - -import org.apache.log4j.Logger; -import org.apache.qpid.server.logging.actors.ManagementActor; -import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.access.Operation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.util.Map; +import java.util.Set; /** * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates @@ -87,8 +87,8 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati return true; } - // Allow querying available object names - if (methodName.equals("queryNames")) + // Allow querying available object names and mbeans + if (methodName.equals("queryNames") || methodName.equals("queryMBeans")) { return true; } @@ -108,7 +108,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - final String methodName = getMethodName(method, args); + String methodName = method.getName(); if (methodName.equals("getMBeanServer")) { @@ -173,6 +173,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati security = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager(); } + methodName = getMethodName(method, args); if (isAccessMethod(methodName) || impact == MBeanOperationInfo.INFO) { // Check for read-only method invocation permission @@ -339,7 +340,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati // Normally JMXManagedObjectRegistry provides a Map as handback data containing a map // between connection id and username. String user = null; - if (handback != null && handback instanceof Map) + if (handback instanceof Map) { final Map<String, String> connectionIdUsernameMap = (Map<String, String>) handback; user = connectionIdUsernameMap.get(connectionId); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java index de14785fb0..483b325455 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObject.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.management; +import org.apache.qpid.AMQException; + +import javax.management.JMException; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; -import javax.management.JMException; - -import org.apache.qpid.AMQException; /** * This should be implemented by all Managable objects. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java index fda80ad0dd..b3323c569c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java @@ -20,12 +20,11 @@ */ package org.apache.qpid.server.management; -import javax.management.JMException; - import org.apache.commons.configuration.ConfigurationException; + import org.apache.qpid.common.Closeable; -import java.rmi.RemoteException; +import javax.management.JMException; import java.io.IOException; /** diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java index a048e75b2e..e77350c3e4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/NoopManagedObjectRegistry.java @@ -20,11 +20,9 @@ */ package org.apache.qpid.server.management; -import javax.management.JMException; - import org.apache.log4j.Logger; -import java.rmi.RemoteException; +import javax.management.JMException; /** * This managed object registry does not actually register MBeans. This can be used in tests when management is diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java index e36e467fea..29b4eac89f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessage.java @@ -21,15 +21,14 @@ package org.apache.qpid.server.message; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.server.configuration.SessionConfig; import org.apache.qpid.server.queue.AMQQueue; - +import org.apache.qpid.server.store.StoredMessage; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; @@ -59,7 +58,7 @@ public class AMQMessage extends AbstractServerMessageImpl<MessageMetaData> private final long _size; - private Object _sessionIdentifier; + private Object _connectionIdentifier; private static final byte IMMEDIATE_AND_DELIVERED = (byte) (IMMEDIATE | DELIVERED_TO_CONSUMER); private WeakReference<AMQChannel> _channelRef; @@ -223,19 +222,15 @@ public class AMQMessage extends AbstractServerMessageImpl<MessageMetaData> } - public Object getPublisherIdentifier() + public Object getConnectionIdentifier() { - //todo store sessionIdentifier/client id with message in store - //Currently the _sessionIdentifier will be null if the message has been - // restored from a message Store - - return _sessionIdentifier; + return _connectionIdentifier; } - public void setClientIdentifier(final Object sessionIdentifier) + public void setConnectionIdentifier(final Object connectionIdentifier) { - _sessionIdentifier = sessionIdentifier; + _connectionIdentifier = connectionIdentifier; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageReference.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageReference.java index 940caaefe4..62cfa8431c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageReference.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AMQMessageReference.java @@ -20,9 +20,6 @@ */ package org.apache.qpid.server.message; -import org.apache.qpid.server.message.AMQMessage; -import org.apache.qpid.server.queue.MessageCleanupException; - public class AMQMessageReference extends MessageReference<AMQMessage> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java index b1d43f0b50..587b76a12e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/AbstractServerMessageImpl.java @@ -20,12 +20,11 @@ */ package org.apache.qpid.server.message; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; - import org.apache.qpid.server.store.StorableMessageMetaData; import org.apache.qpid.server.store.StoredMessage; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + public abstract class AbstractServerMessageImpl<T extends StorableMessageMetaData> implements ServerMessage<T> { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java index 84a1642578..e87b67d242 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.message; -import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; import java.util.Set; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java index 79d5574a91..c6dbb49061 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/InboundMessage.java @@ -21,8 +21,8 @@ package org.apache.qpid.server.message; -import org.apache.qpid.server.queue.Filterable; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.queue.Filterable; public interface InboundMessage extends Filterable { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java index 9bfa0bb2fb..583f0c09a7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java @@ -20,19 +20,21 @@ */ package org.apache.qpid.server.message; -import org.apache.qpid.framing.ContentHeaderBody; +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.EncodingUtils; -import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.server.store.StorableMessageMetaData; import org.apache.qpid.server.store.MessageMetaDataType; -import org.apache.qpid.AMQException; +import org.apache.qpid.server.store.StorableMessageMetaData; import org.apache.qpid.server.util.ByteBufferOutputStream; import org.apache.qpid.util.ByteBufferInputStream; -import java.io.*; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.Set; @@ -159,7 +161,7 @@ public class MessageMetaData implements StorableMessageMetaData public int getContentSize() { - return (int) _contentHeaderBody.bodySize; + return (int) _contentHeaderBody.getBodySize(); } public boolean isPersistent() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java index 17ebb6ee07..88b0f60346 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_0_10.java @@ -20,20 +20,19 @@ */ package org.apache.qpid.server.message; -import org.apache.qpid.server.store.StorableMessageMetaData; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.store.MessageMetaDataType; -import org.apache.qpid.transport.MessageTransfer; +import org.apache.qpid.server.store.StorableMessageMetaData; import org.apache.qpid.transport.DeliveryProperties; -import org.apache.qpid.transport.MessageProperties; import org.apache.qpid.transport.Header; import org.apache.qpid.transport.MessageDeliveryMode; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.MessageTransfer; import org.apache.qpid.transport.Struct; -import org.apache.qpid.transport.codec.BBEncoder; import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.transport.codec.BBEncoder; import java.nio.ByteBuffer; -import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.List; @@ -51,6 +50,7 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes public static final MessageMetaDataType.Factory<MessageMetaData_0_10> FACTORY = new MetaDataFactory(); private volatile ByteBuffer _encoded; + private Object _connectionReference; public MessageMetaData_0_10(MessageTransfer xfr) @@ -220,6 +220,16 @@ public class MessageMetaData_0_10 implements StorableMessageMetaData, InboundMes return _header; } + public void setConnectionReference(Object connectionReference) + { + _connectionReference = connectionReference; + } + + public Object getConnectionReference() + { + return _connectionReference; + } + private static class MetaDataFactory implements MessageMetaDataType.Factory<MessageMetaData_0_10> { public MessageMetaData_0_10 createMetaData(ByteBuffer buf) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java index 2f30f260c9..126e7c28cb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferHeader.java @@ -21,11 +21,11 @@ package org.apache.qpid.server.message; import org.apache.qpid.transport.DeliveryProperties; -import org.apache.qpid.transport.MessageProperties; import org.apache.qpid.transport.MessageDeliveryPriority; +import org.apache.qpid.transport.MessageProperties; -import java.util.Set; import java.util.Map; +import java.util.Set; import java.util.UUID; class MessageTransferHeader implements AMQMessageHeader diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java index c4d2a190e6..e4de65d192 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageTransferMessage.java @@ -20,11 +20,9 @@ */ package org.apache.qpid.server.message; -import org.apache.qpid.transport.*; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.server.transport.ServerSession; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.store.StoredMessage; +import org.apache.qpid.transport.Header; import java.nio.ByteBuffer; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java index d354d3b145..e1ad2fd0ca 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ServerMessage.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.message; -import java.nio.ByteBuffer; - import org.apache.qpid.server.store.StorableMessageMetaData; import org.apache.qpid.server.store.StoredMessage; +import java.nio.ByteBuffer; + public interface ServerMessage<T extends StorableMessageMetaData> extends EnqueableMessage, MessageContentSource { String getRoutingKey(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java index fa06a99204..72d14456ed 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/HeaderPropertiesConverter.java @@ -20,21 +20,28 @@ */ package org.apache.qpid.server.output; +import org.apache.qpid.AMQPInvalidClassException; import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.message.MessageTransferMessage; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.*; -import org.apache.qpid.AMQPInvalidClassException; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageDeliveryMode; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.ReplyTo; import java.util.HashMap; import java.util.Map; public class HeaderPropertiesConverter { + private HeaderPropertiesConverter() + { + } public static BasicContentHeaderProperties convert(MessageTransferMessage messageTransferMessage, VirtualHost vhost) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java index 5300bad613..04d81bf2f5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java @@ -26,14 +26,14 @@ */
package org.apache.qpid.server.output;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.message.MessageContentSource;
-import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-import org.apache.qpid.AMQException;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.QueueEntry;
public interface ProtocolOutputConverter
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java index 9102b6c651..cfdcf7fb43 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9_1/ProtocolOutputConverterImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java @@ -1,4 +1,4 @@ -package org.apache.qpid.server.output.amqp0_9_1; +package org.apache.qpid.server.output; /* * * Licensed to the Apache Software Foundation (ASF) under one @@ -20,45 +20,42 @@ package org.apache.qpid.server.output.amqp0_9_1; * */ -import org.apache.qpid.server.output.ProtocolOutputConverter; -import org.apache.qpid.server.output.HeaderPropertiesConverter; -import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQBody; +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.framing.AMQFrame; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.BasicCancelOkBody; +import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.BasicGetOkBody; +import org.apache.qpid.framing.BasicReturnBody; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import org.apache.qpid.server.message.AMQMessage; -import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.message.MessageContentSource; import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.framing.*; -import org.apache.qpid.framing.amqp_0_91.BasicGetBodyImpl; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.AMQException; +import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.transport.DeliveryProperties; -import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; -public class ProtocolOutputConverterImpl implements ProtocolOutputConverter +class ProtocolOutputConverterImpl implements ProtocolOutputConverter { - private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_91); - - public static Factory getInstanceFactory() - { - return new Factory() - { - - public ProtocolOutputConverter newInstance(AMQProtocolSession session) - { - return new ProtocolOutputConverterImpl(session); - } - }; - } + private static final int BASIC_CLASS_ID = 60; + private final MethodRegistry _methodRegistry; private final AMQProtocolSession _protocolSession; - private ProtocolOutputConverterImpl(AMQProtocolSession session) + ProtocolOutputConverterImpl(AMQProtocolSession session, MethodRegistry methodRegistry) { _protocolSession = session; + _methodRegistry = methodRegistry; } @@ -86,8 +83,8 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter { final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message, entry.getQueue().getVirtualHost()); - ContentHeaderBody chb = new ContentHeaderBody(props, BasicGetBodyImpl.CLASS_ID); - chb.bodySize = message.getSize(); + ContentHeaderBody chb = new ContentHeaderBody(props, BASIC_CLASS_ID); + chb.setBodySize(message.getSize()); return chb; } } @@ -188,15 +185,6 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter } } - private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody) - { - - AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId, - contentHeaderBody); - return contentHeader; - } - - public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException { AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize); @@ -233,11 +221,11 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter final AMQBody returnBlock = new AMQBody() { - public AMQBody _underlyingBody; + private AMQBody _underlyingBody; public AMQBody createAMQBody() { - return METHOD_REGISTRY.createBasicDeliverBody(consumerTag, + return _methodRegistry.createBasicDeliverBody(consumerTag, deliveryTag, isRedelivered, exchangeName, @@ -305,7 +293,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter final boolean isRedelivered = entry.isRedelivered(); BasicGetOkBody getOkBody = - METHOD_REGISTRY.createBasicGetOkBody(deliveryTag, + _methodRegistry.createBasicGetOkBody(deliveryTag, isRedelivered, exchangeName, routingKey, @@ -316,7 +304,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter public byte getProtocolMinorVersion() { - return getProtocolSession().getProtocolMinorVersion(); + return _protocolSession.getProtocolMinorVersion(); } public byte getProtocolMajorVersion() @@ -330,7 +318,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter { BasicReturnBody basicReturnBody = - METHOD_REGISTRY.createBasicReturnBody(replyCode, + _methodRegistry.createBasicReturnBody(replyCode, replyText, messagePublishInfo.getExchange(), messagePublishInfo.getRoutingKey()); @@ -358,7 +346,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag) { - BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag); + BasicCancelOkBody basicCancelOkBody = _methodRegistry.createBasicCancelOkBody(consumerTag); writeFrame(basicCancelOkBody.generateFrame(channelId)); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java index dbefeb61f2..dcbfd89298 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java @@ -26,12 +26,13 @@ */
package org.apache.qpid.server.output;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.server.output.ProtocolOutputConverter.Factory;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.framing.ProtocolVersion;
-import java.util.Map;
import java.util.HashMap;
+import java.util.Map;
public class ProtocolOutputConverterRegistry
{
@@ -42,15 +43,19 @@ public class ProtocolOutputConverterRegistry static
{
- register(ProtocolVersion.v8_0, org.apache.qpid.server.output.amqp0_8.ProtocolOutputConverterImpl.getInstanceFactory());
- register(ProtocolVersion.v0_9, org.apache.qpid.server.output.amqp0_9.ProtocolOutputConverterImpl.getInstanceFactory());
- register(ProtocolVersion.v0_91, org.apache.qpid.server.output.amqp0_9_1.ProtocolOutputConverterImpl.getInstanceFactory());
+ register(ProtocolVersion.v8_0);
+ register(ProtocolVersion.v0_9);
+ register(ProtocolVersion.v0_91);
}
- private static void register(ProtocolVersion version, Factory converter)
+ private ProtocolOutputConverterRegistry()
+ {
+ }
+
+ private static void register(ProtocolVersion version)
{
- _registry.put(version,converter);
+ _registry.put(version,new ConverterFactory(version));
}
@@ -58,4 +63,28 @@ public class ProtocolOutputConverterRegistry {
return _registry.get(session.getProtocolVersion()).newInstance(session);
}
+
+ private static class ConverterFactory implements Factory
+ {
+ private ProtocolVersion _protocolVersion;
+ private MethodRegistry _methodRegistry;
+ private int _classId;
+
+ public ConverterFactory(ProtocolVersion pv)
+ {
+ _protocolVersion = pv;
+
+ }
+
+ public synchronized ProtocolOutputConverter newInstance(AMQProtocolSession session)
+ {
+ if(_methodRegistry == null)
+ {
+
+ _methodRegistry = MethodRegistry.getMethodRegistry(_protocolVersion);
+
+ }
+ return new ProtocolOutputConverterImpl(session, _methodRegistry);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java deleted file mode 100644 index 1e62e5e9ca..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java +++ /dev/null @@ -1,420 +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. - * - */ - -/* - * This file is auto-generated by Qpid Gentools v.0.1 - do not modify. - * Supported AMQP versions: - * 8-0 - */ -package org.apache.qpid.server.output.amqp0_8; - -import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.message.AMQMessage; -import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.output.ProtocolOutputConverter; -import org.apache.qpid.server.output.HeaderPropertiesConverter; -import org.apache.qpid.server.message.MessageContentSource; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.framing.*; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.AMQException; -import org.apache.qpid.transport.DeliveryProperties; - -import java.io.DataOutput; -import java.io.IOException; - -public class ProtocolOutputConverterImpl implements ProtocolOutputConverter -{ - - private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0); - - public static Factory getInstanceFactory() - { - return new Factory() - { - - public ProtocolOutputConverter newInstance(AMQProtocolSession session) - { - return new ProtocolOutputConverterImpl(session); - } - }; - } - - - private final AMQProtocolSession _protocolSession; - - private ProtocolOutputConverterImpl(AMQProtocolSession session) - { - _protocolSession = session; - } - - - public AMQProtocolSession getProtocolSession() - { - return _protocolSession; - } - - public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag) - throws AMQException - { - AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag); - writeMessageDelivery(entry, channelId, deliverBody); - } - - - private ContentHeaderBody getContentHeaderBody(QueueEntry entry) - throws AMQException - { - if(entry.getMessage() instanceof AMQMessage) - { - return ((AMQMessage)entry.getMessage()).getContentHeaderBody(); - } - else - { - final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); - BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message, entry.getQueue().getVirtualHost()); - ContentHeaderBody chb = new ContentHeaderBody(props, org.apache.qpid.framing.amqp_8_0.BasicGetBodyImpl.CLASS_ID); - chb.bodySize = message.getSize(); - return chb; - } - } - - - private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody) - throws AMQException - { - writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody); - } - - private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody) - throws AMQException - { - - - int bodySize = (int) message.getSize(); - - if(bodySize == 0) - { - SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody, - contentHeaderBody); - - writeFrame(compositeBlock); - } - else - { - int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead(); - - - int capacity = bodySize > maxBodySize ? maxBodySize : bodySize; - - int writtenSize = capacity; - - AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity); - - CompositeAMQBodyBlock - compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody); - writeFrame(compositeBlock); - - while(writtenSize < bodySize) - { - capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize; - MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity); - writtenSize += capacity; - - writeFrame(new AMQFrame(channelId, body)); - } - } - } - - private class MessageContentSourceBody implements AMQBody - { - public static final byte TYPE = 3; - private int _length; - private MessageContentSource _message; - private int _offset; - - public MessageContentSourceBody(MessageContentSource message, int offset, int length) - { - _message = message; - _offset = offset; - _length = length; - } - - public byte getFrameType() - { - return TYPE; - } - - public int getSize() - { - return _length; - } - - public void writePayload(DataOutput buffer) throws IOException - { - byte[] data = new byte[_length]; - - _message.getContent(java.nio.ByteBuffer.wrap(data), _offset); - - buffer.write(data); - } - - public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException - { - throw new UnsupportedOperationException(); - } - } - - private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody) - { - - AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId, - contentHeaderBody); - return contentHeader; - } - - - public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException - { - AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize); - writeMessageDelivery(entry, channelId, deliver); - } - - - private AMQBody createEncodedDeliverBody(QueueEntry entry, - final long deliveryTag, - final AMQShortString consumerTag) - throws AMQException - { - - final AMQShortString exchangeName; - final AMQShortString routingKey; - - if(entry.getMessage() instanceof AMQMessage) - { - final AMQMessage message = (AMQMessage) entry.getMessage(); - final MessagePublishInfo pb = message.getMessagePublishInfo(); - exchangeName = pb.getExchange(); - routingKey = pb.getRoutingKey(); - } - else - { - MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); - DeliveryProperties delvProps = message.getHeader().getDeliveryProperties(); - exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange()); - routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey()); - } - - final boolean isRedelivered = entry.isRedelivered(); - - final AMQBody returnBlock = new AMQBody() - { - - public AMQBody _underlyingBody; - - public AMQBody createAMQBody() - { - return METHOD_REGISTRY.createBasicDeliverBody(consumerTag, - deliveryTag, - isRedelivered, - exchangeName, - routingKey); - - - - - - } - - public byte getFrameType() - { - return AMQMethodBody.TYPE; - } - - public int getSize() - { - if(_underlyingBody == null) - { - _underlyingBody = createAMQBody(); - } - return _underlyingBody.getSize(); - } - - 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!"); - } - }; - return returnBlock; - } - - private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize) - throws AMQException - { - final AMQShortString exchangeName; - final AMQShortString routingKey; - - if(entry.getMessage() instanceof AMQMessage) - { - final AMQMessage message = (AMQMessage) entry.getMessage(); - final MessagePublishInfo pb = message.getMessagePublishInfo(); - exchangeName = pb.getExchange(); - routingKey = pb.getRoutingKey(); - } - else - { - MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); - DeliveryProperties delvProps = message.getHeader().getDeliveryProperties(); - exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange()); - routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey()); - } - - final boolean isRedelivered = entry.isRedelivered(); - - BasicGetOkBody getOkBody = - METHOD_REGISTRY.createBasicGetOkBody(deliveryTag, - isRedelivered, - exchangeName, - routingKey, - queueSize); - - return getOkBody; - } - - public byte getProtocolMinorVersion() - { - return getProtocolSession().getProtocolMinorVersion(); - } - - public byte getProtocolMajorVersion() - { - return getProtocolSession().getProtocolMajorVersion(); - } - - private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo, - int replyCode, - AMQShortString replyText) throws AMQException - { - - BasicReturnBody basicReturnBody = - METHOD_REGISTRY.createBasicReturnBody(replyCode, - replyText, - messagePublishInfo.getExchange(), - messagePublishInfo.getRoutingKey()); - - - return basicReturnBody; - } - - public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText) - throws AMQException - { - - AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText); - - writeMessageDelivery(message, header, channelId, returnFrame); - } - - - public void writeFrame(AMQDataBlock block) - { - getProtocolSession().writeFrame(block); - } - - - public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag) - { - - BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag); - writeFrame(basicCancelOkBody.generateFrame(channelId)); - - } - - - public static final class CompositeAMQBodyBlock extends AMQDataBlock - { - public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead(); - - private final AMQBody _methodBody; - private final AMQBody _headerBody; - private final AMQBody _contentBody; - private final int _channel; - - - public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody) - { - _channel = channel; - _methodBody = methodBody; - _headerBody = headerBody; - _contentBody = contentBody; - - } - - public long getSize() - { - return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize(); - } - - public void writePayload(DataOutput buffer) throws IOException - { - AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody); - } - } - - public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock - { - public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead(); - - private final AMQBody _methodBody; - private final AMQBody _headerBody; - private final int _channel; - - - public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody) - { - _channel = channel; - _methodBody = methodBody; - _headerBody = headerBody; - - } - - public long getSize() - { - return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ; - } - - public void writePayload(DataOutput buffer) throws IOException - { - AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody); - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java deleted file mode 100644 index 78507b0cf2..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java +++ /dev/null @@ -1,418 +0,0 @@ -package org.apache.qpid.server.output.amqp0_9; -/* - * - * 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. - * - */ - -import org.apache.qpid.server.output.ProtocolOutputConverter; -import org.apache.qpid.server.output.HeaderPropertiesConverter; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.message.AMQMessage; -import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.message.MessageContentSource; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.framing.*; -import org.apache.qpid.framing.amqp_0_9.BasicGetBodyImpl; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.AMQException; -import org.apache.qpid.transport.DeliveryProperties; -import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; - -import java.io.DataOutput; -import java.io.IOException; -import java.nio.ByteBuffer; - -public class ProtocolOutputConverterImpl implements ProtocolOutputConverter -{ - private static final MethodRegistry METHOD_REGISTRY = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9); - - - public static Factory getInstanceFactory() - { - return new Factory() - { - - public ProtocolOutputConverter newInstance(AMQProtocolSession session) - { - return new ProtocolOutputConverterImpl(session); - } - }; - } - - private final AMQProtocolSession _protocolSession; - - private ProtocolOutputConverterImpl(AMQProtocolSession session) - { - _protocolSession = session; - } - - - public AMQProtocolSession getProtocolSession() - { - return _protocolSession; - } - - public void writeDeliver(QueueEntry entry, int channelId, long deliveryTag, AMQShortString consumerTag) - throws AMQException - { - AMQBody deliverBody = createEncodedDeliverBody(entry, deliveryTag, consumerTag); - writeMessageDelivery(entry, channelId, deliverBody); - } - - - private ContentHeaderBody getContentHeaderBody(QueueEntry entry) - throws AMQException - { - if(entry.getMessage() instanceof AMQMessage) - { - return ((AMQMessage)entry.getMessage()).getContentHeaderBody(); - } - else - { - final MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); - BasicContentHeaderProperties props = HeaderPropertiesConverter.convert(message, entry.getQueue().getVirtualHost()); - ContentHeaderBody chb = new ContentHeaderBody(props, BasicGetBodyImpl.CLASS_ID); - chb.bodySize = message.getSize(); - return chb; - } - } - - - private void writeMessageDelivery(QueueEntry entry, int channelId, AMQBody deliverBody) - throws AMQException - { - writeMessageDelivery(entry.getMessage(), getContentHeaderBody(entry), channelId, deliverBody); - } - - private void writeMessageDelivery(MessageContentSource message, ContentHeaderBody contentHeaderBody, int channelId, AMQBody deliverBody) - throws AMQException - { - - - int bodySize = (int) message.getSize(); - - if(bodySize == 0) - { - SmallCompositeAMQBodyBlock compositeBlock = new SmallCompositeAMQBodyBlock(channelId, deliverBody, - contentHeaderBody); - - writeFrame(compositeBlock); - } - else - { - int maxBodySize = (int) getProtocolSession().getMaxFrameSize() - AMQFrame.getFrameOverhead(); - - - int capacity = bodySize > maxBodySize ? maxBodySize : bodySize; - - int writtenSize = capacity; - - AMQBody firstContentBody = new MessageContentSourceBody(message,0,capacity); - - - CompositeAMQBodyBlock - compositeBlock = new CompositeAMQBodyBlock(channelId, deliverBody, contentHeaderBody, firstContentBody); - writeFrame(compositeBlock); - - while(writtenSize < bodySize) - { - capacity = bodySize - writtenSize > maxBodySize ? maxBodySize : bodySize - writtenSize; - MessageContentSourceBody body = new MessageContentSourceBody(message, writtenSize, capacity); - writtenSize += capacity; - - writeFrame(new AMQFrame(channelId, body)); - } - } - } - - private class MessageContentSourceBody implements AMQBody - { - public static final byte TYPE = 3; - private int _length; - private MessageContentSource _message; - private int _offset; - - public MessageContentSourceBody(MessageContentSource message, int offset, int length) - { - _message = message; - _offset = offset; - _length = length; - } - - public byte getFrameType() - { - return TYPE; - } - - public int getSize() - { - return _length; - } - - public void writePayload(DataOutput buffer) throws IOException - { - byte[] data = new byte[_length]; - - _message.getContent(ByteBuffer.wrap(data), _offset); - - buffer.write(data); - } - - public void handle(int channelId, AMQVersionAwareProtocolSession amqProtocolSession) throws AMQException - { - throw new UnsupportedOperationException(); - } - } - - - private AMQDataBlock createContentHeaderBlock(final int channelId, final ContentHeaderBody contentHeaderBody) - { - - AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId, - contentHeaderBody); - return contentHeader; - } - - - public void writeGetOk(QueueEntry entry, int channelId, long deliveryTag, int queueSize) throws AMQException - { - AMQBody deliver = createEncodedGetOkBody(entry, deliveryTag, queueSize); - writeMessageDelivery(entry, channelId, deliver); - } - - - private AMQBody createEncodedDeliverBody(QueueEntry entry, - final long deliveryTag, - final AMQShortString consumerTag) - throws AMQException - { - - final AMQShortString exchangeName; - final AMQShortString routingKey; - - if(entry.getMessage() instanceof AMQMessage) - { - final AMQMessage message = (AMQMessage) entry.getMessage(); - final MessagePublishInfo pb = message.getMessagePublishInfo(); - exchangeName = pb.getExchange(); - routingKey = pb.getRoutingKey(); - } - else - { - MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); - DeliveryProperties delvProps = message.getHeader().getDeliveryProperties(); - exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange()); - routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey()); - } - - final boolean isRedelivered = entry.isRedelivered(); - - final AMQBody returnBlock = new AMQBody() - { - - public AMQBody _underlyingBody; - - public AMQBody createAMQBody() - { - return METHOD_REGISTRY.createBasicDeliverBody(consumerTag, - deliveryTag, - isRedelivered, - exchangeName, - routingKey); - - - - - - } - - public byte getFrameType() - { - return AMQMethodBody.TYPE; - } - - public int getSize() - { - if(_underlyingBody == null) - { - _underlyingBody = createAMQBody(); - } - return _underlyingBody.getSize(); - } - - 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!"); - } - }; - return returnBlock; - } - - private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize) - throws AMQException - { - final AMQShortString exchangeName; - final AMQShortString routingKey; - - if(entry.getMessage() instanceof AMQMessage) - { - final AMQMessage message = (AMQMessage) entry.getMessage(); - final MessagePublishInfo pb = message.getMessagePublishInfo(); - exchangeName = pb.getExchange(); - routingKey = pb.getRoutingKey(); - } - else - { - MessageTransferMessage message = (MessageTransferMessage) entry.getMessage(); - DeliveryProperties delvProps = message.getHeader().getDeliveryProperties(); - exchangeName = (delvProps == null || delvProps.getExchange() == null) ? null : new AMQShortString(delvProps.getExchange()); - routingKey = (delvProps == null || delvProps.getRoutingKey() == null) ? null : new AMQShortString(delvProps.getRoutingKey()); - } - - final boolean isRedelivered = entry.isRedelivered(); - - BasicGetOkBody getOkBody = - METHOD_REGISTRY.createBasicGetOkBody(deliveryTag, - isRedelivered, - exchangeName, - routingKey, - queueSize); - - return getOkBody; - } - - public byte getProtocolMinorVersion() - { - return getProtocolSession().getProtocolMinorVersion(); - } - - public byte getProtocolMajorVersion() - { - return getProtocolSession().getProtocolMajorVersion(); - } - - private AMQBody createEncodedReturnFrame(MessagePublishInfo messagePublishInfo, - int replyCode, - AMQShortString replyText) throws AMQException - { - - BasicReturnBody basicReturnBody = - METHOD_REGISTRY.createBasicReturnBody(replyCode, - replyText, - messagePublishInfo.getExchange(), - messagePublishInfo.getRoutingKey()); - - - return basicReturnBody; - } - - public void writeReturn(MessagePublishInfo messagePublishInfo, ContentHeaderBody header, MessageContentSource message, int channelId, int replyCode, AMQShortString replyText) - throws AMQException - { - - AMQBody returnFrame = createEncodedReturnFrame(messagePublishInfo, replyCode, replyText); - - writeMessageDelivery(message, header, channelId, returnFrame); - } - - - public void writeFrame(AMQDataBlock block) - { - getProtocolSession().writeFrame(block); - } - - - public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag) - { - - BasicCancelOkBody basicCancelOkBody = METHOD_REGISTRY.createBasicCancelOkBody(consumerTag); - writeFrame(basicCancelOkBody.generateFrame(channelId)); - - } - - - public static final class CompositeAMQBodyBlock extends AMQDataBlock - { - public static final int OVERHEAD = 3 * AMQFrame.getFrameOverhead(); - - private final AMQBody _methodBody; - private final AMQBody _headerBody; - private final AMQBody _contentBody; - private final int _channel; - - - public CompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody, AMQBody contentBody) - { - _channel = channel; - _methodBody = methodBody; - _headerBody = headerBody; - _contentBody = contentBody; - - } - - public long getSize() - { - return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() + _contentBody.getSize(); - } - - public void writePayload(DataOutput buffer) throws IOException - { - AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody); - } - } - - public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock - { - public static final int OVERHEAD = 2 * AMQFrame.getFrameOverhead(); - - private final AMQBody _methodBody; - private final AMQBody _headerBody; - private final int _channel; - - - public SmallCompositeAMQBodyBlock(int channel, AMQBody methodBody, AMQBody headerBody) - { - _channel = channel; - _methodBody = methodBody; - _headerBody = headerBody; - - } - - public long getSize() - { - return OVERHEAD + _methodBody.getSize() + _headerBody.getSize() ; - } - - public void writePayload(DataOutput buffer) throws IOException - { - AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody); - } - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java index df72e87fd8..12e1eee9ca 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java @@ -19,11 +19,12 @@ package org.apache.qpid.server.plugins; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.registry.ApplicationRegistry; 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); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java index 644f714c8c..d2bb3e037c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java @@ -18,11 +18,11 @@ */ package org.apache.qpid.server.plugins; +import org.osgi.framework.Version; + import java.util.Iterator; import java.util.Map; -import org.osgi.framework.Version; - /** * 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: diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java index 804a9d5027..6dcf688f2a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java @@ -19,6 +19,7 @@ package org.apache.qpid.server.plugins; import org.apache.commons.configuration.ConfigurationException; + import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; public interface Plugin diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java index bbf3e74a30..7ea2b95b89 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java @@ -19,6 +19,7 @@ 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> diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java index dab6c3b231..880b1cca8d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java @@ -18,32 +18,17 @@ */ package org.apache.qpid.server.plugins; -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; - -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.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 org.apache.qpid.common.Closeable; import org.apache.qpid.common.QpidProperties; import org.apache.qpid.server.configuration.TopicConfiguration; @@ -54,8 +39,6 @@ import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueCo 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.AllowAll; -import org.apache.qpid.server.security.access.plugins.DenyAll; import org.apache.qpid.server.security.access.plugins.LegacyAccess; import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory; import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; @@ -64,12 +47,28 @@ 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 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 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 @@ -146,16 +145,13 @@ public class PluginManager implements Closeable { // 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( - AllowAll.FACTORY, DenyAll.FACTORY, LegacyAccess.FACTORY)) + for (SecurityPluginFactory<?> pluginFactory : Arrays.asList(LegacyAccess.FACTORY)) { _securityPlugins.put(pluginFactory.getPluginName(), pluginFactory); } for (ConfigurationPluginFactory configFactory : Arrays.asList( TopicConfiguration.FACTORY, SecurityManager.SecurityConfiguration.FACTORY, - AllowAll.AllowAllConfiguration.FACTORY, - DenyAll.DenyAllConfiguration.FACTORY, LegacyAccess.LegacyAccessConfiguration.FACTORY, new SlowConsumerDetectionConfigurationFactory(), new SlowConsumerDetectionPolicyConfigurationFactory(), @@ -254,6 +250,8 @@ public class PluginManager implements Closeable _logger.info("Using the specified external BundleContext"); } + // TODO save trackers in a map, keyed by class name + _exchangeTracker = new ServiceTracker(bundleContext, ExchangeType.class.getName(), null); _exchangeTracker.open(); _trackers.add(_exchangeTracker); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java index bc0d4e3bcc..5af3899890 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java @@ -20,14 +20,14 @@ */ package org.apache.qpid.server.protocol; -import java.util.List; -import java.util.UUID; - import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.stats.StatisticsGatherer; +import java.util.List; +import java.util.UUID; + public interface AMQConnectionModel extends StatisticsGatherer { /** diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java index 547f2440db..e9ad4ea8e0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java @@ -20,34 +20,15 @@ */ package org.apache.qpid.server.protocol; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.security.Principal; -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 javax.management.JMException; -import javax.security.auth.Subject; -import javax.security.sasl.SaslServer; import org.apache.log4j.Logger; + import org.apache.qpid.AMQChannelException; import org.apache.qpid.AMQConnectionException; import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.common.ClientProperties; import org.apache.qpid.framing.*; +import org.apache.qpid.properties.ConnectionStartProperties; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; @@ -83,13 +64,30 @@ 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; + +import javax.management.JMException; +import javax.security.auth.Subject; +import javax.security.sasl.SaslServer; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.security.Principal; +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; public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig { private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class); - private static final String CLIENT_PROPERTIES_INSTANCE = ClientProperties.instance.toString(); - // to save boxing the channelId and looking up in a map... cache in an array the low numbered // channels. This value must be of the form 2^x - 1. private static final int CHANNEL_CACHE_SIZE = 0xff; @@ -97,7 +95,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr private AMQShortString _contextKey; - private AMQShortString _clientVersion = null; + private String _clientVersion = null; private VirtualHost _virtualHost; @@ -119,7 +117,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr private Object _lastSent; - protected volatile boolean _closed; + private volatile boolean _closed; // maximum number of channels this session should have private long _maxNoOfChannels = ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(); @@ -134,9 +132,9 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr private ProtocolOutputConverter _protocolOutputConverter; private Subject _authorizedSubject; private MethodDispatcher _dispatcher; - private ProtocolSessionIdentifier _sessionIdentifier; - private final long _sessionID; + private final long _connectionID; + private Object _reference = new Object(); private AMQPConnectionActor _actor; private LogSubject _logSubject; @@ -174,7 +172,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr _codecFactory = new AMQCodecFactory(true, this); setNetworkConnection(network); - _sessionID = connectionId; + _connectionID = connectionId; _actor = new AMQPConnectionActor(this, virtualHostRegistry.getApplicationRegistry().getRootMessageLogger()); @@ -183,7 +181,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr _configStore = virtualHostRegistry.getConfigStore(); _id = _configStore.createId(); - _actor.message(ConnectionMessages.OPEN(null, null, false, false)); + _actor.message(ConnectionMessages.OPEN(null, null, null, false, false, false)); _registry = virtualHostRegistry.getApplicationRegistry(); initialiseStatistics(); @@ -207,7 +205,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr public long getSessionID() { - return _sessionID; + return _connectionID; } public LogActor getLogActor() @@ -369,7 +367,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr try { // Log incomming protocol negotiation request - _actor.message(ConnectionMessages.OPEN(null, pi._protocolMajor + "-" + pi._protocolMinor, false, true)); + _actor.message(ConnectionMessages.OPEN(null, pi.getProtocolMajor() + "-" + pi.getProtocolMinor(), null, false, true, false)); ProtocolVersion pv = pi.checkVersion(); // Fails if not correct @@ -721,7 +719,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr // However, due to the poor exception handling on the client. The client-user will be notified of the // InvalidArgument and if they then decide to close the session/connection then the there will be time // for that to occur i.e. a new close method be sent before the exeption handling can mark the session closed. - //removeChannel(channelId); + _closingChannelsList.remove(channelId); } @@ -922,31 +920,22 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr _saslServer = saslServer; } - public FieldTable getClientProperties() - { - return _clientProperties; - } - public void setClientProperties(FieldTable clientProperties) { _clientProperties = clientProperties; if (_clientProperties != null) { - if (_clientProperties.getString(CLIENT_PROPERTIES_INSTANCE) != null) + _clientVersion = _clientProperties.getString(ConnectionStartProperties.VERSION_0_8); + + if (_clientProperties.getString(ConnectionStartProperties.CLIENT_ID_0_8) != null) { - String clientID = _clientProperties.getString(CLIENT_PROPERTIES_INSTANCE); + String clientID = _clientProperties.getString(ConnectionStartProperties.CLIENT_ID_0_8); setContextKey(new AMQShortString(clientID)); // Log the Opening of the connection for this client - _actor.message(ConnectionMessages.OPEN(clientID, _protocolVersion.toString(), true, true)); - } - - if (_clientProperties.getString(ClientProperties.version.toString()) != null) - { - _clientVersion = new AMQShortString(_clientProperties.getString(ClientProperties.version.toString())); + _actor.message(ConnectionMessages.OPEN(clientID, _protocolVersion.toString(), _clientVersion, true, true, true)); } } - _sessionIdentifier = new ProtocolSessionIdentifier(this); } private void setProtocolVersion(ProtocolVersion pv) @@ -982,11 +971,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr return getMethodRegistry(); } - public Object getClientIdentifier() - { - return _network.getRemoteAddress(); - } - public VirtualHost getVirtualHost() { return _virtualHost; @@ -1155,14 +1139,9 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr return _lastReceivedTime; } - public ProtocolSessionIdentifier getSessionIdentifier() - { - return _sessionIdentifier; - } - public String getClientVersion() { - return (_clientVersion == null) ? null : _clientVersion.toString(); + return _clientVersion; } public Boolean isIncoming() @@ -1357,6 +1336,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr (Throwable) null)); } + public boolean isClosed() + { + return _closed; + } + public List<AMQSessionModel> getSessionModels() { List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>(); @@ -1457,30 +1441,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr return getAuthorizedPrincipal().getName(); } - private static class ByteBufferOutputStream extends OutputStream - { - - - private final ByteBuffer _buf; - - public ByteBufferOutputStream(ByteBuffer buf) - { - _buf = buf; - } - - @Override - public void write(int b) throws IOException - { - _buf.put((byte) b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException - { - _buf.put(b, off, len); - } - } - public final class WriteDeliverMethod implements ClientDeliveryMethod { @@ -1501,158 +1461,8 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr } - private static class BytesDataOutput implements DataOutput + public Object getReference() { - int _pos = 0; - byte[] _buf; - - public BytesDataOutput(byte[] buf) - { - _buf = buf; - } - - public void setBuffer(byte[] buf) - { - _buf = buf; - _pos = 0; - } - - public void reset() - { - _pos = 0; - } - - public int length() - { - return _pos; - } - - public void write(int b) - { - _buf[_pos++] = (byte) b; - } - - public void write(byte[] b) - { - System.arraycopy(b, 0, _buf, _pos, b.length); - _pos+=b.length; - } - - - public void write(byte[] b, int off, int len) - { - System.arraycopy(b, off, _buf, _pos, len); - _pos+=len; - - } - - public void writeBoolean(boolean v) - { - _buf[_pos++] = v ? (byte) 1 : (byte) 0; - } - - public void writeByte(int v) - { - _buf[_pos++] = (byte) v; - } - - public void writeShort(int v) - { - _buf[_pos++] = (byte) (v >>> 8); - _buf[_pos++] = (byte) v; - } - - public void writeChar(int v) - { - _buf[_pos++] = (byte) (v >>> 8); - _buf[_pos++] = (byte) v; - } - - public void writeInt(int v) - { - _buf[_pos++] = (byte) (v >>> 24); - _buf[_pos++] = (byte) (v >>> 16); - _buf[_pos++] = (byte) (v >>> 8); - _buf[_pos++] = (byte) v; - } - - public void writeLong(long v) - { - _buf[_pos++] = (byte) (v >>> 56); - _buf[_pos++] = (byte) (v >>> 48); - _buf[_pos++] = (byte) (v >>> 40); - _buf[_pos++] = (byte) (v >>> 32); - _buf[_pos++] = (byte) (v >>> 24); - _buf[_pos++] = (byte) (v >>> 16); - _buf[_pos++] = (byte) (v >>> 8); - _buf[_pos++] = (byte)v; - } - - public void writeFloat(float v) - { - writeInt(Float.floatToIntBits(v)); - } - - public void writeDouble(double v) - { - writeLong(Double.doubleToLongBits(v)); - } - - public void writeBytes(String s) - { - int len = s.length(); - for (int i = 0 ; i < len ; i++) - { - _buf[_pos++] = ((byte)s.charAt(i)); - } - } - - public void writeChars(String s) - { - int len = s.length(); - for (int i = 0 ; i < len ; i++) - { - int v = s.charAt(i); - _buf[_pos++] = (byte) (v >>> 8); - _buf[_pos++] = (byte) v; - } - } - - public void writeUTF(String s) - { - int strlen = s.length(); - - int pos = _pos; - _pos+=2; - - - for (int i = 0; i < strlen; i++) - { - int c = s.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) - { - c = s.charAt(i); - _buf[_pos++] = (byte) c; - - } - else if (c > 0x07FF) - { - _buf[_pos++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); - _buf[_pos++] = (byte) (0x80 | ((c >> 6) & 0x3F)); - _buf[_pos++] = (byte) (0x80 | (c & 0x3F)); - } - else - { - _buf[_pos++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); - _buf[_pos++] = (byte) (0x80 | (c & 0x3F)); - } - } - - int len = _pos - (pos + 2); - - _buf[pos++] = (byte) (len >>> 8); - _buf[pos] = (byte) len; - } - + return _reference; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java index dfba10750c..6cd5b21f89 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java @@ -20,23 +20,25 @@ */ package org.apache.qpid.server.protocol; +import java.util.List; + import javax.security.auth.Subject; import javax.security.sasl.SaslServer; -import org.apache.qpid.AMQException; -import org.apache.qpid.common.ClientProperties; -import org.apache.qpid.framing.*; import org.apache.qpid.AMQConnectionException; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.MethodDispatcher; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.output.ProtocolOutputConverter; +import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.virtualhost.VirtualHost; -import java.util.List; - public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, AuthorizationHolder, AMQConnectionModel { @@ -58,28 +60,6 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth long getLastReceivedTime(); - public static final class ProtocolSessionIdentifier - { - private final Object _sessionIdentifier; - private final Object _sessionInstance; - - ProtocolSessionIdentifier(AMQProtocolSession session) - { - _sessionIdentifier = session.getClientIdentifier(); - _sessionInstance = session.getClientProperties() == null ? null : session.getClientProperties().getObject(ClientProperties.instance.toAMQShortString()); - } - - public Object getSessionIdentifier() - { - return _sessionIdentifier; - } - - public Object getSessionInstance() - { - return _sessionInstance; - } - } - public static interface Task { public void doTask(AMQProtocolSession session) throws AMQException; @@ -190,12 +170,9 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth */ void setSaslServer(SaslServer saslServer); - - FieldTable getClientProperties(); - void setClientProperties(FieldTable clientProperties); - Object getClientIdentifier(); + Object getReference(); VirtualHost getVirtualHost(); @@ -215,8 +192,6 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth public MethodDispatcher getMethodDispatcher(); - public ProtocolSessionIdentifier getSessionIdentifier(); - String getClientVersion(); long getLastIoTime(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java index 8d39420631..e70720600e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java @@ -22,7 +22,7 @@ * * Copyright (c) 2006 The Apache Software Foundation * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -37,16 +37,6 @@ */ package org.apache.qpid.server.protocol; -import java.util.Date; -import java.util.List; -import javax.management.JMException; -import javax.management.MBeanException; -import javax.management.NotCompliantMBeanException; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; @@ -60,6 +50,17 @@ import org.apache.qpid.server.logging.actors.ManagementActor; import org.apache.qpid.server.management.AbstractAMQManagedConnectionObject; import org.apache.qpid.server.management.ManagedObject; +import javax.management.JMException; +import javax.management.MBeanException; +import javax.management.NotCompliantMBeanException; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import java.util.Date; +import java.util.List; + /** * This MBean class implements the management interface. In order to make more attributes, operations and notifications * available over JMX simply augment the ManagedConnection interface and add the appropriate implementation here. @@ -91,7 +92,7 @@ public class AMQProtocolSessionMBean extends AbstractAMQManagedConnectionObject public String getVersion() { - return (_protocolSession.getClientVersion() == null) ? null : _protocolSession.getClientVersion().toString(); + return _protocolSession.getClientVersion(); } public Date getLastIoTime() @@ -132,7 +133,7 @@ public class AMQProtocolSessionMBean extends AbstractAMQManagedConnectionObject */ public void commitTransactions(int channelId) throws JMException { - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { AMQChannel channel = _protocolSession.getChannel(channelId); @@ -161,7 +162,7 @@ public class AMQProtocolSessionMBean extends AbstractAMQManagedConnectionObject */ public void rollbackTransactions(int channelId) throws JMException { - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { AMQChannel channel = _protocolSession.getChannel(channelId); @@ -240,7 +241,7 @@ public class AMQProtocolSessionMBean extends AbstractAMQManagedConnectionObject if (CurrentActor.get() == null) { removeActor = true; - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); } try diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java index c55fe321fc..a69f2a74ee 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java @@ -20,12 +20,20 @@ */ package org.apache.qpid.server.protocol; +import java.util.concurrent.ConcurrentSkipListSet; + import org.apache.qpid.AMQException; import org.apache.qpid.server.logging.LogSubject; +import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.SimpleAMQQueue; -public interface AMQSessionModel +/** + * Session model interface. + * Extends {@link Comparable} to allow objects to be inserted into a {@link ConcurrentSkipListSet} + * when monitoring the blocking and blocking of queues/sessions in {@link SimpleAMQQueue}. + */ +public interface AMQSessionModel extends Comparable<AMQSessionModel> { public Object getID(); @@ -57,4 +65,7 @@ public interface AMQSessionModel void block(AMQQueue queue); void unblock(AMQQueue queue); + + + boolean onSameConnection(InboundMessage inbound); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java index a71d396919..ce20690f66 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java @@ -21,6 +21,11 @@ package org.apache.qpid.server.protocol; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.util.Set; + import org.apache.log4j.Logger; import org.apache.qpid.protocol.ServerProtocolEngine; import org.apache.qpid.server.registry.IApplicationRegistry; @@ -29,10 +34,6 @@ import org.apache.qpid.transport.ConnectionDelegate; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.NetworkConnection; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.util.Set; - public class MultiVersionProtocolEngine implements ServerProtocolEngine { private static final Logger _logger = Logger.getLogger(MultiVersionProtocolEngine.class); @@ -44,29 +45,35 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine private IApplicationRegistry _appRegistry; private NetworkConnection _network; private Sender<ByteBuffer> _sender; + private final AmqpProtocolVersion _defaultSupportedReply; private volatile ServerProtocolEngine _delegate = new SelfDelegateProtocolEngine(); - public MultiVersionProtocolEngine(IApplicationRegistry appRegistry, - String fqdn, - Set<AmqpProtocolVersion> supported, - NetworkConnection network, - long id) + public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry, + final Set<AmqpProtocolVersion> supported, + final AmqpProtocolVersion defaultSupportedReply, + final long id, + final NetworkConnection network) { - this(appRegistry,fqdn,supported,id); + this(appRegistry, supported, defaultSupportedReply, id); setNetworkConnection(network); } - public MultiVersionProtocolEngine(IApplicationRegistry appRegistry, - String fqdn, - Set<AmqpProtocolVersion> supported, - long id) + public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry, + final Set<AmqpProtocolVersion> supported, + final AmqpProtocolVersion defaultSupportedReply, + final long id) { + if(defaultSupportedReply != null && !supported.contains(defaultSupportedReply)) + { + throw new IllegalArgumentException("The configured default reply (" + defaultSupportedReply + + ") to an unsupported protocol version initiation is itself not supported!"); + } + _id = id; _appRegistry = appRegistry; - _fqdn = fqdn; _supported = supported; - + _defaultSupportedReply = defaultSupportedReply; } @@ -198,6 +205,15 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public void setNetworkConnection(NetworkConnection network, Sender<ByteBuffer> sender) { _network = network; + SocketAddress address = _network.getLocalAddress(); + if (address instanceof InetSocketAddress) + { + _fqdn = ((InetSocketAddress) address).getHostName(); + } + else + { + throw new IllegalArgumentException("Unsupported socket address class: " + address); + } _sender = sender; } @@ -445,14 +461,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine ServerProtocolEngine newDelegate = null; - byte[] newestSupported = null; + byte[] supportedReplyBytes = null; + byte[] defaultSupportedReplyBytes = null; + AmqpProtocolVersion supportedReplyVersion = null; + //Check the supported versions for a header match, and if there is one save the + //delegate. Also save most recent supported version and associated reply header bytes for(int i = 0; newDelegate == null && i < _creators.length; i++) { - if(_supported.contains(_creators[i].getVersion())) { - newestSupported = _creators[i].getHeaderIdentifier(); + supportedReplyBytes = _creators[i].getHeaderIdentifier(); + supportedReplyVersion = _creators[i].getVersion(); byte[] compareBytes = _creators[i].getHeaderIdentifier(); boolean equal = true; for(int j = 0; equal && j<compareBytes.length; j++) @@ -464,12 +484,35 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine newDelegate = _creators[i].getProtocolEngine(); } } + + //If there is a configured default reply to an unsupported version initiation, + //then save the associated reply header bytes when we encounter them + if(_defaultSupportedReply != null && _creators[i].getVersion() == _defaultSupportedReply) + { + defaultSupportedReplyBytes = _creators[i].getHeaderIdentifier(); + } } - // If no delegate is found then send back the most recent support protocol version id + // If no delegate is found then send back a supported protocol version id if(newDelegate == null) { - _sender.send(ByteBuffer.wrap(newestSupported)); + //if a default reply was specified use its reply header instead of the most recent supported version + if(_defaultSupportedReply != null && !(_defaultSupportedReply == supportedReplyVersion)) + { + if(_logger.isDebugEnabled()) + { + _logger.debug("Default reply to unsupported protocol version was configured, changing reply from " + + supportedReplyVersion + " to " + _defaultSupportedReply); + } + + supportedReplyBytes = defaultSupportedReplyBytes; + supportedReplyVersion = _defaultSupportedReply; + } + if(_logger.isDebugEnabled()) + { + _logger.debug("Unsupported protocol version requested, replying with: " + supportedReplyVersion); + } + _sender.send(ByteBuffer.wrap(supportedReplyBytes)); _sender.flush(); _delegate = new ClosedDelegateProtocolEngine(); @@ -482,7 +525,6 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine _delegate = newDelegate; _header.flip(); - _delegate.setNetworkConnection(_network, _sender); _delegate.received(_header); if(msg.hasRemaining()) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java index 7e327b221f..552b1c7054 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java @@ -20,38 +20,38 @@ */ package org.apache.qpid.server.protocol; -import java.util.Set; -import java.util.concurrent.atomic.AtomicLong; - 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.transport.network.NetworkConnection; + +import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory { private static final AtomicLong ID_GENERATOR = new AtomicLong(0); private final IApplicationRegistry _appRegistry; - private final String _fqdn; private final Set<AmqpProtocolVersion> _supported; + private final AmqpProtocolVersion _defaultSupportedReply; - public MultiVersionProtocolEngineFactory(String fqdn, Set<AmqpProtocolVersion> supportedVersions) + public MultiVersionProtocolEngineFactory(final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply) { + if(defaultSupportedReply != null && !supportedVersions.contains(defaultSupportedReply)) + { + throw new IllegalArgumentException("The configured default reply (" + defaultSupportedReply + + ") to an unsupported protocol version initiation is itself not supported!"); + } + _appRegistry = ApplicationRegistry.getInstance(); - _fqdn = fqdn; _supported = supportedVersions; - } - - public ServerProtocolEngine newProtocolEngine(NetworkConnection network) - { - return new MultiVersionProtocolEngine(_appRegistry, _fqdn, _supported, network, ID_GENERATOR.getAndIncrement()); + _defaultSupportedReply = defaultSupportedReply; } public ServerProtocolEngine newProtocolEngine() { - return new MultiVersionProtocolEngine(_appRegistry, _fqdn, _supported, ID_GENERATOR.getAndIncrement()); + return new MultiVersionProtocolEngine(_appRegistry, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement()); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java index 5d4b8c603b..182ef1ed82 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java @@ -21,15 +21,19 @@ 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.InputHandler; import org.apache.qpid.transport.network.Assembler; import org.apache.qpid.transport.network.Disassembler; +import org.apache.qpid.transport.network.InputHandler; import org.apache.qpid.transport.network.NetworkConnection; -import org.apache.qpid.server.configuration.*; -import org.apache.qpid.server.transport.ServerConnection; -import org.apache.qpid.server.logging.messages.ConnectionMessages; -import org.apache.qpid.server.registry.IApplicationRegistry; import java.net.SocketAddress; import java.nio.ByteBuffer; @@ -86,8 +90,8 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol _connection.setSender(new Disassembler(sender, MAX_FRAME_SIZE)); // FIXME Two log messages to maintain compatibility with earlier protocol versions - _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, false, false)); - _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", false, true)); + _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, null, false, false, false)); + _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", null, false, true, false)); } public SocketAddress getRemoteAddress() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java index ed9d58994a..de2e1b69da 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java @@ -29,7 +29,6 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.apache.qpid.AMQException; import org.apache.qpid.AMQInternalException; -import org.apache.qpid.AMQInvalidArgumentException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler; import org.apache.qpid.amqp_1_0.transport.LinkEndpoint; @@ -54,6 +53,7 @@ import org.apache.qpid.amqp_1_0.type.transport.AmqpError; import org.apache.qpid.amqp_1_0.type.transport.Detach; import org.apache.qpid.amqp_1_0.type.transport.Error; import org.apache.qpid.amqp_1_0.type.transport.Transfer; +import org.apache.qpid.filter.selector.ParseException; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.TopicExchange; @@ -135,7 +135,7 @@ public class SendingLink_1_0 implements SendingLinkListener, Link_1_0, DeliveryS actualFilters.put(entry.getKey(), entry.getValue()); } - catch (AMQInvalidArgumentException e) + catch (ParseException e) { Error error = new Error(); error.setCondition(AmqpError.INVALID_FIELD); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java index 2c04a626ff..f6bf6626a0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java @@ -20,9 +20,10 @@ */ package org.apache.qpid.server.queue; -import java.util.Map; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Map; + public class AMQPriorityQueue extends OutOfOrderQueue { protected AMQPriorityQueue(final String name, @@ -39,6 +40,6 @@ public class AMQPriorityQueue extends OutOfOrderQueue public int getPriorities() { - return ((PriorityQueueList) _entries).getPriorities(); + return ((PriorityQueueList) getEntries()).getPriorities(); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java index 32d9c4878a..e643338c3d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java @@ -22,20 +22,18 @@ package org.apache.qpid.server.queue; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.logging.LogSubject; -import org.apache.qpid.server.protocol.AMQSessionModel; 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.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeReferrer; +import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.store.TransactionLogResource; import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.virtualhost.VirtualHost; import java.util.List; @@ -142,10 +140,9 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer public List<QueueEntry> getMessagesRangeOnTheQueue(final long fromPosition, final long toPosition); - void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, - ServerTransaction transaction); + void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName); - void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName, ServerTransaction transaction); + void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName); void removeMessagesFromQueue(long fromMessageId, long toMessageId); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java index 14ca147982..e04ab8cfe9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.server.queue; -import java.util.HashMap; -import java.util.Map; import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.exchange.ExchangeDefaults; @@ -35,6 +33,9 @@ import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.HashMap; +import java.util.Map; + public class AMQQueueFactory { public static final String X_QPID_PRIORITIES = "x-qpid-priorities"; @@ -48,6 +49,10 @@ public class AMQQueueFactory public static final String X_QPID_MAXIMUM_DELIVERY_COUNT = "x-qpid-maximum-delivery-count"; public static final String DEFAULT_DLQ_NAME_SUFFIX = "_DLQ"; + private AMQQueueFactory() + { + } + private abstract static class QueueProperty { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java index 143a6ae8ca..b0d4cb3486 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.queue; +import org.apache.commons.lang.time.FastDateFormat; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; @@ -31,12 +32,10 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.ManagedObject; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.AMQMessage; +import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.txn.ServerTransaction; -import org.apache.qpid.server.txn.LocalTransaction; +import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.transport.MessageProperties; import javax.management.JMException; @@ -56,9 +55,10 @@ import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; -import java.text.SimpleDateFormat; -import java.util.*; /** * AMQQueueMBean is the management bean for an {@link AMQQueue}. @@ -72,11 +72,13 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que { /** Used for debugging purposes. */ - private static final Logger _logger = Logger.getLogger(AMQQueueMBean.class); + private static final Logger LOGGER = Logger.getLogger(AMQQueueMBean.class); /** Date/time format used for message expiration and message timestamp formatting */ public static final String JMSTIMESTAMP_DATETIME_FORMAT = "MM-dd-yy HH:mm:ss.SSS z"; + private static final FastDateFormat FAST_DATE_FORMAT = FastDateFormat.getInstance(JMSTIMESTAMP_DATETIME_FORMAT); + private final AMQQueue _queue; private final String _queueName; // OpenMBean data types for viewMessages method @@ -347,14 +349,14 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que public void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg) { // important : add log to the log file - monitoring tools may be looking for this - _logger.info(notification.name() + " On Queue " + queue.getNameShortString() + " - " + notificationMsg); + LOGGER.info(notification.name() + " On Queue " + queue.getNameShortString() + " - " + notificationMsg); notificationMsg = notification.name() + " " + notificationMsg; _lastNotification = - new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, ++_notificationSequenceNumber, + new Notification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED, this, incrementAndGetSequenceNumber(), System.currentTimeMillis(), notificationMsg); - _broadcaster.sendNotification(_lastNotification); + getBroadcaster().sendNotification(_lastNotification); } public Notification getLastNotification() @@ -491,7 +493,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que ContentHeaderBody headerBody = msg.getContentHeaderBody(); // Create header attributes list headerAttributes = getMessageHeaderProperties(headerBody); - itemValues = new Object[]{msg.getMessageId(), headerAttributes, headerBody.bodySize, queueEntry.isRedelivered(), position, queueEntry.getDeliveryCount()}; + itemValues = new Object[]{msg.getMessageId(), headerAttributes, headerBody.getBodySize(), queueEntry.isRedelivered(), position, queueEntry.getDeliveryCount()}; } else if(serverMsg instanceof MessageTransferMessage) { @@ -589,18 +591,8 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que private void addStringifiedJMSTimestamoAndJMSExpiration(final List<String> list, final long expirationDate, final long timestampDate) { - final SimpleDateFormat dateFormat; - if (expirationDate != 0 || timestampDate != 0) - { - dateFormat = new SimpleDateFormat(JMSTIMESTAMP_DATETIME_FORMAT); - } - else - { - dateFormat = null; - } - - final String formattedExpirationDate = (expirationDate != 0) ? dateFormat.format(new Date(expirationDate)) : null; - final String formattedTimestampDate = (timestampDate != 0) ? dateFormat.format(new Date(timestampDate)) : null; + final String formattedExpirationDate = (expirationDate != 0) ? FAST_DATE_FORMAT.format(expirationDate) : null; + final String formattedTimestampDate = (timestampDate != 0) ? FAST_DATE_FORMAT.format(timestampDate) : null; list.add("JMSExpiration = " + formattedExpirationDate); list.add("JMSTimestamp = " + formattedTimestampDate); } @@ -619,9 +611,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\""); } - ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getMessageStore()); - _queue.moveMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, txn); - txn.commit(); + _queue.moveMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName); } /** @@ -654,13 +644,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que throw new OperationsException("\"From MessageId\" should be greater than 0 and less than \"To MessageId\""); } - ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getMessageStore()); - - _queue.copyMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName, txn); - - txn.commit(); - - + _queue.copyMessagesToAnotherQueue(fromMessageId, toMessageId, toQueueName); } /** diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java index 0bd40e8f13..35b7cac1a1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/BaseQueue.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.queue; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.store.TransactionLogResource; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.store.TransactionLogResource; public interface BaseQueue extends TransactionLogResource { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java index b5293f51be..2c645cc555 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueue.java @@ -41,7 +41,7 @@ public class ConflationQueue extends SimpleAMQQueue public String getConflationKey() { - return ((ConflationQueueList) _entries).getConflationKey(); + return ((ConflationQueueList) getEntries()).getConflationKey(); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java index ab0a567114..6a2e4f155d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ConflationQueueList.java @@ -21,13 +21,13 @@ package org.apache.qpid.server.queue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; - import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; + public class ConflationQueueList extends SimpleQueueEntryList { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/Filterable.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/Filterable.java index eaa3992e98..50d8f4166d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/Filterable.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/Filterable.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.AMQException; import org.apache.qpid.server.message.AMQMessageHeader; public interface Filterable diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java index 31e9725e47..bbc33ca846 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.queue; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.message.AMQMessageHeader; +import org.apache.qpid.server.message.InboundMessage; public class InboundMessageAdapter implements InboundMessage { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java index 19a7a15ad1..c5a610c7b6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java @@ -20,25 +20,26 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.framing.abstraction.ContentChunk; -import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.log4j.Logger; + +import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.message.AMQMessageHeader; 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.AMQException; -import org.apache.log4j.Logger; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.store.StoredMessage; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.nio.ByteBuffer; public class IncomingMessage implements Filterable, InboundMessage, EnqueableMessage, MessageContentSource { @@ -69,8 +70,6 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes private Exchange _exchange; - - private int _receivedChunkCount = 0; private List<ContentChunk> _contentChunks = new ArrayList<ContentChunk>(); // we keep both the original meta data object and the store reference to it just in case the @@ -79,13 +78,20 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes private MessageMetaData _messageMetaData; private StoredMessage<MessageMetaData> _storedMessageHandle; + private Object _connectionReference; public IncomingMessage( final MessagePublishInfo info ) { + this(info, null); + } + + public IncomingMessage(MessagePublishInfo info, Object reference) + { _messagePublishInfo = info; + _connectionReference = reference; } public void setContentHeaderBody(final ContentHeaderBody contentHeaderBody) throws AMQException @@ -124,12 +130,6 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes } - public MessageMetaData headersReceived() - { - - return headersReceived(System.currentTimeMillis()); - } - public MessageMetaData headersReceived(long currentTime) { _messageMetaData = new MessageMetaData(_messagePublishInfo, _contentHeaderBody, 0, currentTime); @@ -142,21 +142,15 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes return _destinationQueues; } - public int addContentBodyFrame(final ContentChunk contentChunk) - throws AMQException + public void addContentBodyFrame(final ContentChunk contentChunk) throws AMQException { - _storedMessageHandle.addContent((int)_bodyLengthReceived, ByteBuffer.wrap(contentChunk.getData())); _bodyLengthReceived += contentChunk.getSize(); _contentChunks.add(contentChunk); - - - - return _receivedChunkCount++; } public boolean allContentReceived() { - return (_bodyLengthReceived == getContentHeader().bodySize); + return (_bodyLengthReceived == getContentHeader().getBodySize()); } public AMQShortString getExchange() @@ -217,7 +211,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes public long getSize() { - return getContentHeader().bodySize; + return getContentHeader().getBodySize(); } public long getMessageNumber() @@ -251,18 +245,12 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes return _expiration; } - public int getReceivedChunkCount() - { - return _receivedChunkCount; - } - - public int getBodyCount() throws AMQException { return _contentChunks.size(); } - public ContentChunk getContentChunk(int index) throws IllegalArgumentException, AMQException + public ContentChunk getContentChunk(int index) { return _contentChunks.get(index); } @@ -317,4 +305,14 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes { return _storedMessageHandle; } + + public Object getConnectionReference() + { + return _connectionReference; + } + + public MessageMetaData getMessageMetaData() + { + return _messageMetaData; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java index d1fb0f3fe6..c1ebbe412f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java @@ -20,7 +20,6 @@ */
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
import org.apache.qpid.server.message.ServerMessage;
public enum NotificationCheck
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java index 0220a553a7..53121fc031 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/OutOfOrderQueue.java @@ -1,11 +1,11 @@ package org.apache.qpid.server.queue; -import java.util.Map; - import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionList; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Map; + public abstract class OutOfOrderQueue extends SimpleAMQQueue { @@ -20,7 +20,7 @@ public abstract class OutOfOrderQueue extends SimpleAMQQueue protected void checkSubscriptionsNotAheadOfDelivery(final QueueEntry entry) { // check that all subscriptions are not in advance of the entry - SubscriptionList.SubscriptionNodeIterator subIter = _subscriptionList.iterator(); + SubscriptionList.SubscriptionNodeIterator subIter = getSubscriptionList().iterator(); while(subIter.advance() && !entry.isAcquired()) { final Subscription subscription = subIter.getNode().getSubscription(); @@ -29,7 +29,7 @@ public abstract class OutOfOrderQueue extends SimpleAMQQueue QueueContext context = (QueueContext) subscription.getQueueContext(); if(context != null) { - QueueEntry released = context._releasedEntry; + QueueEntry released = context.getReleasedEntry(); while(!entry.isAcquired() && (released == null || released.compareTo(entry) > 0)) { if(QueueContext._releasedUpdater.compareAndSet(context,released,entry)) @@ -38,7 +38,7 @@ public abstract class OutOfOrderQueue extends SimpleAMQQueue } else { - released = context._releasedEntry; + released = context.getReleasedEntry(); } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java index 79d3ab5bd0..05141a48a1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java @@ -74,7 +74,7 @@ public class PriorityQueueList implements QueueEntryList<SimpleQueueEntryImpl> { final QueueEntryList<?> nodeEntryList = node.getQueueEntryList(); int index; - for(index = _priorityLists.length-1; _priorityLists[index] != nodeEntryList; index--); + for(index = _priorityLists.length-1; _priorityLists[index] != nodeEntryList; index--) {}; while(next == null && index != 0) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java index 825a85a89c..c8f04c7b96 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java @@ -25,8 +25,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; final class QueueContext implements AMQQueue.Context { - volatile QueueEntry _lastSeenEntry; - volatile QueueEntry _releasedEntry; + private volatile QueueEntry _lastSeenEntry; + private volatile QueueEntry _releasedEntry; static final AtomicReferenceFieldUpdater<QueueContext, QueueEntry> _lastSeenUpdater = @@ -46,4 +46,10 @@ final class QueueContext implements AMQQueue.Context { return _lastSeenEntry; } + + + QueueEntry getReleasedEntry() + { + return _releasedEntry; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java index 142cfddb39..c33309b6d3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java @@ -1,10 +1,8 @@ package org.apache.qpid.server.queue; -import java.util.Collection; - import org.apache.qpid.AMQException; -import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.subscription.Subscription; /* * diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java index 82c6a2f127..404907183a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java @@ -34,7 +34,6 @@ import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.subscription.Subscription; -import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.LocalTransaction; import org.apache.qpid.server.txn.ServerTransaction; @@ -416,11 +415,19 @@ public abstract class QueueEntryImpl implements QueueEntry if (alternateExchange != null) { - final List<? extends BaseQueue> rerouteQueues = alternateExchange.route(new InboundMessageAdapter(this)); + InboundMessageAdapter inboundMessageAdapter = new InboundMessageAdapter(this); + List<? extends BaseQueue> queues = alternateExchange.route(inboundMessageAdapter); final ServerMessage message = getMessage(); - if (rerouteQueues != null && rerouteQueues.size() != 0) + if ((queues == null || queues.size() == 0) && alternateExchange.getAlternateExchange() != null) { + queues = alternateExchange.getAlternateExchange().route(inboundMessageAdapter); + } + + + if (queues != null && queues.size() != 0) + { + final List<? extends BaseQueue> rerouteQueues = queues; ServerTransaction txn = new LocalTransaction(getQueue().getVirtualHost().getMessageStore()); txn.enqueue(rerouteQueues, message, new ServerTransaction.Action() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java index a537e0c83f..80f6bd1493 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.queue; -import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.virtualhost.VirtualHost; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java index 0d44fe7cf3..22a2029494 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java @@ -20,17 +20,16 @@ */ package org.apache.qpid.server.queue; -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.queue.QueueRunner; -import org.apache.qpid.server.queue.SimpleAMQQueue; - import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.transport.TransportException; + /** * QueueRunners are Runnables used to process a queue when requiring * asynchronous message delivery to subscriptions, which is necessary @@ -47,7 +46,6 @@ public class QueueRunner implements Runnable private static int SCHEDULED = 1; private static int RUNNING = 2; - private final AtomicInteger _scheduled = new AtomicInteger(IDLE); private final AtomicBoolean _stateChange = new AtomicBoolean(); @@ -55,8 +53,6 @@ public class QueueRunner implements Runnable private final AtomicLong _lastRunAgain = new AtomicLong(); private final AtomicLong _lastRunTime = new AtomicLong(); - private long _continues; - public QueueRunner(SimpleAMQQueue queue) { _queue = queue; @@ -74,24 +70,35 @@ public class QueueRunner implements Runnable runAgain = _queue.processQueue(this); } - catch (AMQException e) + catch (final AMQException e) { _logger.error("Exception during asynchronous delivery by " + toString(), e); } - finally + catch (final TransportException transe) { - CurrentActor.remove(); + final String errorMessage = "Problem during asynchronous delivery by " + toString(); + if(_logger.isDebugEnabled()) + { + _logger.debug(errorMessage, transe); + } + else + { + _logger.info(errorMessage + ' ' + transe.getMessage()); + } } - _scheduled.compareAndSet(RUNNING, IDLE); - long stateChangeCount = _queue.getStateChangeCount(); - _lastRunAgain.set(runAgain); - _lastRunTime.set(System.nanoTime()); - if(runAgain == 0L || runAgain != stateChangeCount || _stateChange.compareAndSet(true,false)) + finally { - _continues++; - if(_scheduled.compareAndSet(IDLE, SCHEDULED)) + CurrentActor.remove(); + _scheduled.compareAndSet(RUNNING, IDLE); + final long stateChangeCount = _queue.getStateChangeCount(); + _lastRunAgain.set(runAgain); + _lastRunTime.set(System.nanoTime()); + if(runAgain == 0L || runAgain != stateChangeCount || _stateChange.compareAndSet(true,false)) { - _queue.execute(this); + if(_scheduled.compareAndSet(IDLE, SCHEDULED)) + { + _queue.execute(this); + } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java index dfad9157c5..c37d0e2202 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java @@ -27,12 +27,16 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import javax.management.JMException; + +import javax.management.JMException; + import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; @@ -99,13 +103,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private Exchange _alternateExchange; - /** Used to track bindings to exchanges so that on deletion they can easily be cancelled. */ + private final QueueEntryList<QueueEntry> _entries; - - protected final QueueEntryList _entries; - - protected final SubscriptionList _subscriptionList = new SubscriptionList(); + private final SubscriptionList _subscriptionList = new SubscriptionList(); private volatile Subscription _exclusiveSubscriber; @@ -137,19 +138,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private final AtomicInteger _bindingCountHigh = new AtomicInteger(); /** max allowed size(KB) of a single message */ - public long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize(); + private long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize(); /** max allowed number of messages on a queue. */ - public long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount(); + private long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount(); /** max queue depth for the queue */ - public long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth(); + private long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth(); /** maximum message age before alerts occur */ - public long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge(); + private long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge(); /** the minimum interval between sending out consecutive alerts of the same type */ - public long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap(); + private long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap(); private long _capacity = ApplicationRegistry.getInstance().getConfiguration().getCapacity(); @@ -167,7 +168,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private AtomicInteger _deliveredMessages = new AtomicInteger(); private AtomicBoolean _stopped = new AtomicBoolean(false); - private final ConcurrentMap<AMQSessionModel, Boolean> _blockedChannels = new ConcurrentHashMap<AMQSessionModel, Boolean>(); + private final Set<AMQSessionModel> _blockedChannels = new ConcurrentSkipListSet<AMQSessionModel>(); private final AtomicBoolean _deleted = new AtomicBoolean(false); private final List<Task> _deleteTaskList = new CopyOnWriteArrayList<Task>(); @@ -455,7 +456,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } } - _activeSubscriberCount.incrementAndGet(); + if(subscription.isActive()) + { + _activeSubscriberCount.incrementAndGet(); + } subscription.setStateListener(this); subscription.setQueueContext(new QueueContext(_entries.getHead())); @@ -778,7 +782,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private boolean mightAssign(final Subscription sub, final QueueEntry entry) { if(_messageGroupManager == null || !sub.acquires()) + { return true; + } Subscription assigned = _messageGroupManager.getAssignedSubscription(entry); return (assigned == null) || (assigned == sub); } @@ -848,7 +854,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes QueueContext context = (QueueContext) subscription.getQueueContext(); if(context != null) { - QueueEntry subnode = context._lastSeenEntry; + QueueEntry subnode = context.getLastSeenEntry(); if(subnode.compareTo(entry)<0) { return false; @@ -872,7 +878,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private void setLastSeenEntry(final Subscription sub, final QueueEntry entry) { QueueContext subContext = (QueueContext) sub.getQueueContext(); - QueueEntry releasedEntry = subContext._releasedEntry; + QueueEntry releasedEntry = subContext.getReleasedEntry(); QueueContext._lastSeenUpdater.set(subContext, entry); if(releasedEntry == entry) @@ -889,7 +895,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes { QueueEntry oldEntry; - while((oldEntry = subContext._releasedEntry) == null || oldEntry.compareTo(entry) > 0) + while((oldEntry = subContext.getReleasedEntry()) == null || oldEntry.compareTo(entry) > 0) { if(QueueContext._releasedUpdater.compareAndSet(subContext, oldEntry, entry)) { @@ -1113,6 +1119,17 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes return _stateChangeCount.get(); } + /** Used to track bindings to exchanges so that on deletion they can easily be cancelled. */ + protected QueueEntryList getEntries() + { + return _entries; + } + + protected SubscriptionList getSubscriptionList() + { + return _subscriptionList; + } + public static interface QueueEntryFilter { @@ -1226,19 +1243,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes public void moveMessagesToAnotherQueue(final long fromMessageId, final long toMessageId, - String queueName, - ServerTransaction txn) throws IllegalArgumentException + String destinationQueueName) throws IllegalArgumentException { - final AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); - if (toQueue == null) - { - throw new IllegalArgumentException("Queue '" + queueName + "' is not registered with the virtualhost."); - } - else if (toQueue == this) - { - throw new IllegalArgumentException("The destination queue cant be the same as the source queue"); - } + final AMQQueue toQueue = getValidatedDestinationQueue(destinationQueueName); List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter() { @@ -1258,65 +1266,68 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes }); - - // Move the messages in on the message store. - for (final QueueEntry entry : entries) + final ServerTransaction txn = new LocalTransaction(getVirtualHost().getMessageStore()); + boolean shouldRollback = true; + try { - final ServerMessage message = entry.getMessage(); - txn.enqueue(toQueue, message, - new ServerTransaction.Action() - { - - public void postCommit() + // Move the messages in on the message store. + for (final QueueEntry entry : entries) + { + final ServerMessage message = entry.getMessage(); + txn.enqueue(toQueue, message, + new ServerTransaction.Action() { - try + + public void postCommit() { - toQueue.enqueue(message); + try + { + toQueue.enqueue(message); + } + catch (AMQException e) + { + throw new RuntimeException(e); + } } - catch (AMQException e) + + public void onRollback() { - throw new RuntimeException(e); + entry.release(); } - } - - public void onRollback() + }); + txn.dequeue(this, message, + new ServerTransaction.Action() { - entry.release(); - } - }); - txn.dequeue(this, message, - new ServerTransaction.Action() - { - public void postCommit() - { - entry.discard(); - } - - public void onRollback() - { + public void postCommit() + { + entry.discard(); + } - } - }); + public void onRollback() + { + } + }); + } + txn.commit(); + shouldRollback = false; + } + finally + { + if (shouldRollback) + { + txn.rollback(); + } } } public void copyMessagesToAnotherQueue(final long fromMessageId, final long toMessageId, - String queueName, - final ServerTransaction txn) throws IllegalArgumentException + String destinationQueueName) throws IllegalArgumentException { - final AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); - if (toQueue == null) - { - throw new IllegalArgumentException("Queue '" + queueName + "' is not registered with the virtualhost."); - } - else if (toQueue == this) - { - throw new IllegalArgumentException("The destination queue cant be the same as the source queue"); - } + final AMQQueue toQueue = getValidatedDestinationQueue(destinationQueueName); List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter() { @@ -1334,36 +1345,63 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } }); - - // Move the messages in on the message store. - for (QueueEntry entry : entries) + final ServerTransaction txn = new LocalTransaction(_virtualHost.getMessageStore()); + boolean shouldRollback = true; + try { - final ServerMessage message = entry.getMessage(); - - txn.enqueue(toQueue, message, new ServerTransaction.Action() + // Copy the messages in on the message store. + for (QueueEntry entry : entries) { - public void postCommit() + final ServerMessage message = entry.getMessage(); + + txn.enqueue(toQueue, message, new ServerTransaction.Action() { - try + public void postCommit() { - toQueue.enqueue(message); + try + { + toQueue.enqueue(message); + } + catch (AMQException e) + { + throw new RuntimeException(e); + } } - catch (AMQException e) + + public void onRollback() { - throw new RuntimeException(e); } - } - - public void onRollback() - { + }); - } - }); + } + txn.commit(); + shouldRollback = false; + } + finally + { + if (shouldRollback) + { + txn.rollback(); + } } } + private AMQQueue getValidatedDestinationQueue(String queueName) + { + final AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName)); + if (toQueue == null) + { + throw new IllegalArgumentException("Queue '" + queueName + "' is not registered with the virtualhost."); + } + else if (toQueue == this) + { + throw new IllegalArgumentException("The destination queue can't be the same as the source queue"); + } + return toQueue; + } + public void removeMessagesFromQueue(long fromMessageId, long toMessageId) { @@ -1543,10 +1581,16 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes for(final QueueEntry entry : entries) { adapter.setEntry(entry); - final List<? extends BaseQueue> rerouteQueues = _alternateExchange.route(adapter); + List<? extends BaseQueue> queues = _alternateExchange.route(adapter); + if((queues == null || queues.size() == 0) && _alternateExchange.getAlternateExchange() != null) + { + queues = _alternateExchange.getAlternateExchange().route(adapter); + } + final ServerMessage message = entry.getMessage(); - if(rerouteQueues != null && rerouteQueues.size() != 0) + if(queues != null && queues.size() != 0) { + final List<? extends BaseQueue> rerouteQueues = queues; txn.enqueue(rerouteQueues, entry.getMessage(), new ServerTransaction.Action() { @@ -1659,7 +1703,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes //Overfull log message _logActor.message(_logSubject, QueueMessages.OVERFULL(_atomicQueueSize.get(), _capacity)); - _blockedChannels.putIfAbsent(channel, Boolean.TRUE); + _blockedChannels.add(channel); channel.block(this); @@ -1692,11 +1736,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes _logActor.message(_logSubject, QueueMessages.UNDERFULL(_atomicQueueSize.get(), _flowResumeCapacity)); } - - for(AMQSessionModel c : _blockedChannels.keySet()) + for(final AMQSessionModel blockedChannel : _blockedChannels) { - c.unblock(this); - _blockedChannels.remove(c); + blockedChannel.unblock(this); + _blockedChannels.remove(blockedChannel); } } } @@ -1714,7 +1757,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes public void deliverAsync(Subscription sub) { - //_stateChangeCount.incrementAndGet(); if(_exclusiveSubscriber == null) { deliverAsync(); @@ -1890,8 +1932,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes QueueContext context = (QueueContext) sub.getQueueContext(); if(context != null) { - QueueEntry lastSeen = context._lastSeenEntry; - QueueEntry releasedNode = context._releasedEntry; + QueueEntry lastSeen = context.getLastSeenEntry(); + QueueEntry releasedNode = context.getReleasedEntry(); QueueEntry node = (releasedNode != null && lastSeen.compareTo(releasedNode)>=0) ? releasedNode : _entries.next(lastSeen); @@ -1913,8 +1955,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes QueueContext._releasedUpdater.compareAndSet(context, releasedNode, null); } - lastSeen = context._lastSeenEntry; - releasedNode = context._releasedEntry; + lastSeen = context.getLastSeenEntry(); + releasedNode = context.getReleasedEntry(); node = (releasedNode != null && lastSeen.compareTo(releasedNode)>0) ? releasedNode : _entries.next(lastSeen); } return node; @@ -1930,8 +1972,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes QueueContext context = (QueueContext) sub.getQueueContext(); if(context != null) { - QueueEntry releasedNode = context._releasedEntry; - return releasedNode == null || releasedNode.compareTo(entry) < 0; + QueueEntry releasedNode = context.getReleasedEntry(); + return releasedNode != null && releasedNode.compareTo(entry) < 0; } else { @@ -2255,8 +2297,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes public boolean equals(Object o) { - return o != null - && o instanceof SimpleAMQQueue.QueueEntryListener + return o instanceof SimpleAMQQueue.QueueEntryListener && _sub == ((QueueEntryListener) o)._sub; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryImpl.java index 0707dc045c..4a10d31d37 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryImpl.java @@ -22,9 +22,16 @@ package org.apache.qpid.server.queue; import org.apache.qpid.server.message.ServerMessage; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + public class SimpleQueueEntryImpl extends QueueEntryImpl { - volatile SimpleQueueEntryImpl _next; + static final AtomicReferenceFieldUpdater<SimpleQueueEntryImpl, SimpleQueueEntryImpl> + _nextUpdater = + AtomicReferenceFieldUpdater.newUpdater + (SimpleQueueEntryImpl.class, SimpleQueueEntryImpl.class, "_next"); + + private volatile SimpleQueueEntryImpl _next; public SimpleQueueEntryImpl(SimpleQueueEntryList queueEntryList) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java index b40e5a28c2..c82d1b984a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java @@ -20,9 +20,11 @@ */ package org.apache.qpid.server.queue; +import org.apache.qpid.server.message.ServerMessage; + import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; -import org.apache.qpid.server.message.ServerMessage; public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl> { @@ -40,12 +42,11 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl private final AMQQueue _queue; static final AtomicReferenceFieldUpdater<SimpleQueueEntryImpl, SimpleQueueEntryImpl> - _nextUpdater = - AtomicReferenceFieldUpdater.newUpdater - (SimpleQueueEntryImpl.class, SimpleQueueEntryImpl.class, "_next"); + _nextUpdater = SimpleQueueEntryImpl._nextUpdater; private AtomicLong _scavenges = new AtomicLong(0L); private final long _scavengeCount = Integer.getInteger("qpid.queue.scavenge_count", 50); + private final AtomicReference<SimpleQueueEntryImpl> _unscavengedHWM = new AtomicReference<SimpleQueueEntryImpl>(); public SimpleQueueEntryList(AMQQueue queue) @@ -55,28 +56,17 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl _tail = _head; } - void advanceHead() - { - SimpleQueueEntryImpl next = _head.getNextNode(); - SimpleQueueEntryImpl newNext = _head.getNextValidEntry(); - - if (next == newNext) - { - if (_scavenges.incrementAndGet() > _scavengeCount) - { - _scavenges.set(0L); - scavenge(); - } - } - } - void scavenge() { + SimpleQueueEntryImpl hwm = _unscavengedHWM.getAndSet(null); SimpleQueueEntryImpl next = _head.getNextValidEntry(); - while (next != null) + if(hwm != null) { - next = next.getNextValidEntry(); + while (next != null && hwm.compareTo(next)>0) + { + next = next.getNextValidEntry(); + } } } @@ -126,7 +116,6 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl public static class QueueEntryIteratorImpl implements QueueEntryIterator<SimpleQueueEntryImpl> { - private SimpleQueueEntryImpl _lastNode; QueueEntryIteratorImpl(SimpleQueueEntryImpl startNode) @@ -134,10 +123,9 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl _lastNode = startNode; } - public boolean atTail() { - return _lastNode.getNextNode() == null; + return _lastNode.getNextValidEntry() == null; } public SimpleQueueEntryImpl getNode() @@ -147,28 +135,17 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl public boolean advance() { + SimpleQueueEntryImpl nextValidNode = _lastNode.getNextValidEntry(); - if(!atTail()) + if(nextValidNode != null) { - SimpleQueueEntryImpl nextNode = _lastNode.getNextNode(); - while(nextNode.isDispensed() && nextNode.getNextNode() != null) - { - nextNode = nextNode.getNextNode(); - } - _lastNode = nextNode; - return true; - - } - else - { - return false; + _lastNode = nextValidNode; } + return nextValidNode != null; } - } - public QueueEntryIteratorImpl iterator() { return new QueueEntryIteratorImpl(_head); @@ -182,7 +159,32 @@ public class SimpleQueueEntryList implements QueueEntryList<SimpleQueueEntryImpl public void entryDeleted(SimpleQueueEntryImpl queueEntry) { - advanceHead(); + SimpleQueueEntryImpl next = _head.getNextNode(); + SimpleQueueEntryImpl newNext = _head.getNextValidEntry(); + + // the head of the queue has not been deleted, hence the deletion must have been mid queue. + if (next == newNext) + { + SimpleQueueEntryImpl unscavengedHWM = _unscavengedHWM.get(); + while(unscavengedHWM == null || unscavengedHWM.compareTo(queueEntry)<0) + { + _unscavengedHWM.compareAndSet(unscavengedHWM, queueEntry); + unscavengedHWM = _unscavengedHWM.get(); + } + if (_scavenges.incrementAndGet() > _scavengeCount) + { + _scavenges.set(0L); + scavenge(); + } + } + else + { + SimpleQueueEntryImpl unscavengedHWM = _unscavengedHWM.get(); + if(unscavengedHWM != null && (next == null || unscavengedHWM.compareTo(next) < 0)) + { + _unscavengedHWM.compareAndSet(unscavengedHWM, null); + } + } } public int getPriorities() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueue.java index 865b3d1f48..446f57b142 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueue.java @@ -19,11 +19,12 @@ */ package org.apache.qpid.server.queue; -import java.util.Map; import org.apache.qpid.AMQException; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.virtualhost.VirtualHost; +import java.util.Map; + public class SortedQueue extends OutOfOrderQueue { //Lock object to synchronize enqueue. Used instead of the object diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java index 414a123c43..7f742d455d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SortedQueueEntryList.java @@ -21,12 +21,7 @@ package org.apache.qpid.server.queue; import org.apache.qpid.server.message.ServerMessage; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.server.queue.SortedQueueEntryImpl.Colour; -import org.apache.qpid.server.store.StoreContext; /** * A sorted implementation of QueueEntryList. @@ -367,7 +362,7 @@ public class SortedQueueEntryList implements QueueEntryList<SortedQueueEntryImpl if(chosenChild != null) { - // we have one child (x), we can move it up to replace x; + // we have one child (x), we can move it up to replace x chosenChild.setParent(entry.getParent()); if(chosenChild.getParent() == null) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java index 48f2efb342..8f3b7ae4ce 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SubFlushRunner.java @@ -21,14 +21,16 @@ package org.apache.qpid.server.queue; */ -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.transport.TransportException; + +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; class SubFlushRunner implements Runnable @@ -67,18 +69,30 @@ class SubFlushRunner implements Runnable } catch (AMQException e) { - _logger.error(e); + _logger.error("Exception during asynchronous delivery by " + toString(), e); } - finally + catch (final TransportException transe) { - CurrentActor.remove(); + final String errorMessage = "Problem during asynchronous delivery by " + toString(); + if(_logger.isDebugEnabled()) + { + _logger.debug(errorMessage, transe); + } + else + { + _logger.info(errorMessage + ' ' + transe.getMessage()); + } } - _scheduled.compareAndSet(RUNNING, IDLE); - if ((!complete || _stateChange.compareAndSet(true,false))&& !_sub.isSuspended()) + finally { - if(_scheduled.compareAndSet(IDLE,SCHEDULED)) + CurrentActor.remove(); + _scheduled.compareAndSet(RUNNING, IDLE); + if ((!complete || _stateChange.compareAndSet(true,false))&& !_sub.isSuspended()) { - getQueue().execute(this); + if(_scheduled.compareAndSet(IDLE,SCHEDULED)) + { + getQueue().execute(this); + } } } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java index 6753cf4560..9951f7d3c8 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java @@ -20,18 +20,10 @@ */ package org.apache.qpid.server.registry; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; +import org.osgi.framework.BundleContext; + import org.apache.qpid.AMQException; import org.apache.qpid.common.Closeable; import org.apache.qpid.common.QpidProperties; @@ -45,6 +37,7 @@ import org.apache.qpid.server.configuration.SystemConfigImpl; import org.apache.qpid.server.configuration.VirtualHostConfiguration; 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.RootMessageLogger; import org.apache.qpid.server.logging.SystemOutMessageLogger; import org.apache.qpid.server.logging.actors.AbstractActor; @@ -65,7 +58,16 @@ import org.apache.qpid.server.transport.QpidAcceptor; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostImpl; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -import org.osgi.framework.BundleContext; + +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; /** @@ -76,33 +78,33 @@ import org.osgi.framework.BundleContext; */ public abstract class ApplicationRegistry implements IApplicationRegistry { - protected static final Logger _logger = Logger.getLogger(ApplicationRegistry.class); + private static final Logger _logger = Logger.getLogger(ApplicationRegistry.class); private static AtomicReference<IApplicationRegistry> _instance = new AtomicReference<IApplicationRegistry>(null); - protected final ServerConfiguration _configuration; + private final ServerConfiguration _configuration; - protected final Map<InetSocketAddress, QpidAcceptor> _acceptors = new HashMap<InetSocketAddress, QpidAcceptor>(); + private final Map<InetSocketAddress, QpidAcceptor> _acceptors = new HashMap<InetSocketAddress, QpidAcceptor>(); - protected ManagedObjectRegistry _managedObjectRegistry; + private ManagedObjectRegistry _managedObjectRegistry; - protected AuthenticationManager _authenticationManager; + private AuthenticationManager _authenticationManager; - protected VirtualHostRegistry _virtualHostRegistry; + private VirtualHostRegistry _virtualHostRegistry; - protected SecurityManager _securityManager; + private SecurityManager _securityManager; - protected PluginManager _pluginManager; + private PluginManager _pluginManager; - protected ConfigurationManager _configurationManager; + private ConfigurationManager _configurationManager; - protected RootMessageLogger _rootMessageLogger; + private RootMessageLogger _rootMessageLogger; - protected CompositeStartupMessageLogger _startupMessageLogger; + private CompositeStartupMessageLogger _startupMessageLogger; - protected UUID _brokerId = UUID.randomUUID(); + private UUID _brokerId = UUID.randomUUID(); - protected QMFService _qmfService; + private QMFService _qmfService; private BrokerConfig _broker; @@ -114,17 +116,74 @@ public abstract class ApplicationRegistry implements IApplicationRegistry private BundleContext _bundleContext; - static + protected static Logger get_logger() { - Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownService())); + return _logger; } - private static class ShutdownService implements Runnable + protected Map<InetSocketAddress, QpidAcceptor> getAcceptors() { - public void run() - { - remove(); - } + return _acceptors; + } + + protected void setManagedObjectRegistry(ManagedObjectRegistry managedObjectRegistry) + { + _managedObjectRegistry = managedObjectRegistry; + } + + protected void setAuthenticationManager(AuthenticationManager authenticationManager) + { + _authenticationManager = authenticationManager; + } + + protected void setVirtualHostRegistry(VirtualHostRegistry virtualHostRegistry) + { + _virtualHostRegistry = virtualHostRegistry; + } + + protected void setSecurityManager(SecurityManager securityManager) + { + _securityManager = securityManager; + } + + protected void setPluginManager(PluginManager pluginManager) + { + _pluginManager = pluginManager; + } + + protected void setConfigurationManager(ConfigurationManager configurationManager) + { + _configurationManager = configurationManager; + } + + protected void setRootMessageLogger(RootMessageLogger rootMessageLogger) + { + _rootMessageLogger = rootMessageLogger; + } + + protected CompositeStartupMessageLogger getStartupMessageLogger() + { + return _startupMessageLogger; + } + + protected void setStartupMessageLogger(CompositeStartupMessageLogger startupMessageLogger) + { + _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 @@ -201,7 +260,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry _logger.info("Shutting down ApplicationRegistry(" + instance + ")"); } instance.close(); - instance.getBroker().getSystem().removeBroker(instance.getBroker()); } } catch (Exception e) @@ -256,7 +314,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry _qmfService = new QMFService(getConfigStore(), this); - CurrentActor.get().message(BrokerMessages.STARTUP(QpidProperties.getReleaseVersion(), QpidProperties.getBuildVersion())); + logStartupMessages(CurrentActor.get()); _virtualHostRegistry = new VirtualHostRegistry(this); @@ -285,6 +343,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } } + /** * Iterates across all discovered authentication manager factories, offering the security configuration to each. * Expects <b>exactly</b> one authentication manager to configure and initialise itself. @@ -358,57 +417,71 @@ public abstract class ApplicationRegistry implements IApplicationRegistry { _reportingTimer = new Timer("Statistics-Reporting", true); - class StatisticsReportingTask extends TimerTask + + + _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(broker, virtualhost, reset), + report / 2, + report); + } + } + + private class StatisticsReportingTask extends TimerTask + { + private final int DELIVERED = 0; + private final int RECEIVED = 1; + + private boolean _broker; + private boolean _virtualhost; + private boolean _reset; + + + public StatisticsReportingTask(boolean broker, boolean virtualhost, boolean reset) + { + _broker = broker; + _virtualhost = virtualhost; + _reset = reset; + } + + public void run() + { + CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) { + public String getLogMessage() + { + return "[" + Thread.currentThread().getName() + "] "; + } + }); + + if (_broker) { - private final int DELIVERED = 0; - private final int RECEIVED = 1; - - public void run() + 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())); + } + + if (_virtualhost) + { + for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts()) { - CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) { - public String getLogMessage() - { - return "[" + Thread.currentThread().getName() + "] "; - } - }); - - if (broker) - { - 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())); - } - - if (virtualhost) - { - for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts()) - { - 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) - { - resetStatistics(); - } - - CurrentActor.remove(); + 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())); } } - _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(), - report / 2, - report); + if (_reset) + { + resetStatistics(); + } + + CurrentActor.remove(); } } @@ -449,35 +522,49 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } } - public void close() { if (_logger.isInfoEnabled()) { _logger.info("Shutting down ApplicationRegistry:" + this); } - - //Stop Statistics Reporting - if (_reportingTimer != null) + + //Set the Actor for Broker Shutdown + CurrentActor.set(new BrokerActor(getRootMessageLogger())); + try { - _reportingTimer.cancel(); - } + //Stop Statistics Reporting + if (_reportingTimer != null) + { + _reportingTimer.cancel(); + } - //Stop incoming connections - unbind(); + //Stop incoming connections + unbind(); - //Shutdown virtualhosts - close(_virtualHostRegistry); + //Shutdown virtualhosts + close(_virtualHostRegistry); - close(_authenticationManager); + close(_authenticationManager); - close(_qmfService); + close(_qmfService); - close(_pluginManager); + close(_pluginManager); - close(_managedObjectRegistry); + close(_managedObjectRegistry); - CurrentActor.get().message(BrokerMessages.STOPPED()); + BrokerConfig broker = getBroker(); + if(broker != null) + { + broker.getSystem().removeBroker(broker); + } + + CurrentActor.get().message(BrokerMessages.STOPPED()); + } + finally + { + CurrentActor.remove(); + } } private void unbind() @@ -654,4 +741,18 @@ public abstract class ApplicationRegistry implements IApplicationRegistry { _statisticsEnabled = enabled; } + + private void logStartupMessages(LogActor logActor) + { + logActor.message(BrokerMessages.STARTUP(QpidProperties.getReleaseVersion(), QpidProperties.getBuildVersion())); + + logActor.message(BrokerMessages.PLATFORM(System.getProperty("java.vendor"), + System.getProperty("java.runtime.version", System.getProperty("java.version")), + System.getProperty("os.name"), + System.getProperty("os.version"), + System.getProperty("os.arch"))); + + logActor.message(BrokerMessages.MAX_MEMORY(Runtime.getRuntime().maxMemory())); + } + } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java index f77b8d2dfa..58fdc99dd3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java @@ -20,16 +20,21 @@ */ package org.apache.qpid.server.registry; -import org.apache.qpid.server.configuration.*; -import org.apache.qpid.server.virtualhost.VirtualHost; 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.UUID; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public class BrokerConfigAdapter implements BrokerConfig diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java index 9121f8f927..b28e3d6c89 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java @@ -20,16 +20,15 @@ */ package org.apache.qpid.server.registry; -import java.io.File; - import org.apache.commons.configuration.ConfigurationException; +import org.osgi.framework.BundleContext; + import org.apache.qpid.AMQException; import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.logging.actors.BrokerActor; -import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.management.JMXManagedObjectRegistry; import org.apache.qpid.server.management.NoopManagedObjectRegistry; -import org.osgi.framework.BundleContext; + +import java.io.File; public class ConfigurationFileApplicationRegistry extends ApplicationRegistry { @@ -44,31 +43,15 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry } @Override - public void close() - { - //Set the Actor for Broker Shutdown - CurrentActor.set(new BrokerActor(_rootMessageLogger)); - try - { - super.close(); - } - finally - { - CurrentActor.remove(); - } - } - - - @Override protected void initialiseManagedObjectRegistry() throws AMQException { - if (_configuration.getManagementEnabled()) + if (getConfiguration().getManagementEnabled()) { - _managedObjectRegistry = new JMXManagedObjectRegistry(); + setManagedObjectRegistry(new JMXManagedObjectRegistry()); } else { - _managedObjectRegistry = new NoopManagedObjectRegistry(); + setManagedObjectRegistry(new NoopManagedObjectRegistry()); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java index c27e0d19ec..59bf250590 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java @@ -20,15 +20,12 @@ */ package org.apache.qpid.server.registry; -import java.net.InetSocketAddress; -import java.util.UUID; - 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.configuration.ConfigurationManager; import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.management.ManagedObjectRegistry; import org.apache.qpid.server.plugins.PluginManager; @@ -39,6 +36,9 @@ 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.util.UUID; + public interface IApplicationRegistry extends StatisticsGatherer { /** diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java index ff80499bc2..704e50da5c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.security; -import org.apache.commons.configuration.ConfigurationException; 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; @@ -32,9 +32,9 @@ import org.apache.qpid.server.security.access.Operation; */ public abstract class AbstractPlugin implements SecurityPlugin { - protected final Logger _logger = Logger.getLogger(getClass()); + private final Logger _logger = Logger.getLogger(getClass()); - protected ConfigurationPlugin _config; + private ConfigurationPlugin _config; public Result getDefault() { @@ -50,4 +50,8 @@ public abstract class AbstractPlugin implements SecurityPlugin _config = config; } + public ConfigurationPlugin getConfig() + { + return _config; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java index ec11e2d39c..236931e8cd 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.security; -import org.apache.commons.configuration.Configuration; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; @@ -28,8 +27,6 @@ import org.apache.qpid.server.security.access.Operation; /** * This {@link SecurityPlugin} proxies the authorise calls to a serries of methods, one per {@link Operation}. * - * Plugins that extend this class should override the relevant authorise method and implement their own - * {@link #setConfiguration(Configuration)} method. */ public abstract class AbstractProxyPlugin extends AbstractPlugin { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java index 3d8c77a86f..8f3bdf7738 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java @@ -20,12 +20,8 @@ */ package org.apache.qpid.server.security; -import java.security.Principal; - import javax.security.auth.Subject; - -import org.apache.qpid.server.security.auth.sasl.GroupPrincipal; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import java.security.Principal; /** * Represents the authorization of the logged on user. @@ -35,8 +31,8 @@ public interface AuthorizationHolder { /** * Returns the {@link Subject} of the authorized user. This is guaranteed to - * contain at least one {@link UsernamePrincipal}, representing the the identity - * used when the user logged on to the application, and zero or more {@link GroupPrincipal} + * contain at least one {@link org.apache.qpid.server.security.auth.sasl.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. * * @return the Subject diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java index 2a1ae8a870..436660cfaf 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java @@ -18,6 +18,19 @@ */ 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.queue.AMQQueue; +import org.apache.qpid.server.security.access.ObjectProperties; +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.METHOD; import static org.apache.qpid.server.security.access.ObjectType.QUEUE; @@ -30,26 +43,17 @@ import static org.apache.qpid.server.security.access.Operation.PUBLISH; import static org.apache.qpid.server.security.access.Operation.PURGE; import static org.apache.qpid.server.security.access.Operation.UNBIND; +import javax.security.auth.Subject; import java.net.SocketAddress; -import java.security.Principal; -import java.util.*; +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; -import javax.security.auth.Subject; - -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.queue.AMQQueue; -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.Operation; - /** * The security manager contains references to all loaded {@link SecurityPlugin}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 @@ -61,7 +65,7 @@ public class SecurityManager { private static final Logger _logger = Logger.getLogger(SecurityManager.class); - /** Container for the {@link Principal} that is using to this thread. */ + /** 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>() { @@ -101,7 +105,7 @@ public class SecurityManager public void validateConfiguration() throws ConfigurationException { - if (_configuration.isEmpty()) + if (getConfig().isEmpty()) { throw new ConfigurationException("security section is incomplete, no elements found."); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java index 5ee7833c4c..21c2d1cda5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java @@ -21,10 +21,11 @@ package org.apache.qpid.server.security; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; 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}. */ diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java index 8a52d31f97..a9ec4d1647 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java @@ -18,13 +18,17 @@ */ package org.apache.qpid.server.security.access; -import java.util.*; - 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.List; +import java.util.Map; + /** * An set of properties for an access control v2 rule {@link ObjectType}. * @@ -315,19 +319,28 @@ public class ObjectProperties || ruleValue.equals(STAR) || (ruleValue.endsWith(STAR) && thisValue != null - && thisValue.length() > ruleValue.length() - && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 2))); + && thisValue.length() >= ruleValue.length() - 1 + && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 1))); } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } ObjectProperties that = (ObjectProperties) o; - if (_properties != null ? !_properties.equals(that._properties) : that._properties != null) return false; + if (_properties != null ? !_properties.equals(that._properties) : that._properties != null) + { + return false; + } return true; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java index 69c7ff185a..90ecd1dd17 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java @@ -18,7 +18,15 @@ */ package org.apache.qpid.server.security.access; -import static org.apache.qpid.server.security.access.Operation.*; +import static org.apache.qpid.server.security.access.Operation.ACCESS; +import static org.apache.qpid.server.security.access.Operation.BIND; +import static org.apache.qpid.server.security.access.Operation.CONSUME; +import static org.apache.qpid.server.security.access.Operation.CREATE; +import static org.apache.qpid.server.security.access.Operation.DELETE; +import static org.apache.qpid.server.security.access.Operation.PUBLISH; +import static org.apache.qpid.server.security.access.Operation.PURGE; +import static org.apache.qpid.server.security.access.Operation.UNBIND; +import static org.apache.qpid.server.security.access.Operation.UPDATE; import java.util.EnumSet; import java.util.Set; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java deleted file mode 100644 index db18a89231..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.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.security.access.plugins; - -import java.util.Arrays; -import java.util.List; - -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.Result; -import org.apache.qpid.server.security.SecurityPluginFactory; - -/** Always allow. */ -public class AllowAll extends BasicPlugin -{ - public static class AllowAllConfiguration extends ConfigurationPlugin { - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.allow-all", "virtualhosts.virtualhost.security.allow-all"); - } - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - ConfigurationPlugin instance = new AllowAllConfiguration(); - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] { "" }; - } - - public void validateConfiguration() throws ConfigurationException - { -// if (!_configuration.isEmpty()) -// { -// throw new ConfigurationException("allow-all section takes no elements."); -// } - } - - } - - public static final SecurityPluginFactory<AllowAll> FACTORY = new SecurityPluginFactory<AllowAll>() - { - public AllowAll newInstance(ConfigurationPlugin config) throws ConfigurationException - { - AllowAllConfiguration configuration = config.getConfiguration(AllowAllConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - return null; - } - - AllowAll plugin = new AllowAll(); - plugin.configure(configuration); - return plugin; - } - - public String getPluginName() - { - return AllowAll.class.getName(); - } - - public Class<AllowAll> getPluginClass() - { - return AllowAll.class; - } - }; - - @Override - public Result getDefault() - { - return Result.ALLOWED; - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java index f3161551dc..4df135a4ca 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java @@ -20,16 +20,14 @@ */ package org.apache.qpid.server.security.access.plugins; -import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.server.security.AbstractPlugin; import org.apache.qpid.server.security.Result; -import org.apache.qpid.server.security.SecurityPlugin; 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} simply abstains from all authorisation requests and ignores configuration. + * This {@link org.apache.qpid.server.security.SecurityPlugin} simply abstains from all authorisation requests and ignores configuration. */ public abstract class BasicPlugin extends AbstractPlugin { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java deleted file mode 100644 index 6c0fb1eaa4..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.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.security.access.plugins; - -import java.util.Arrays; -import java.util.List; - -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.Result; -import org.apache.qpid.server.security.SecurityPluginFactory; - -/** Always Deny. */ -public class DenyAll extends BasicPlugin -{ - public static class DenyAllConfiguration extends ConfigurationPlugin { - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.deny-all", "virtualhosts.virtualhost.security.deny-all"); - } - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - ConfigurationPlugin instance = new DenyAllConfiguration(); - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] { "" }; - } - - public void validateConfiguration() throws ConfigurationException - { - if (!_configuration.isEmpty()) - { - throw new ConfigurationException("deny-all section takes no elements."); - } - } - - } - - public static final SecurityPluginFactory<DenyAll> FACTORY = new SecurityPluginFactory<DenyAll>() - { - public DenyAll newInstance(ConfigurationPlugin config) throws ConfigurationException - { - DenyAllConfiguration configuration = config.getConfiguration(DenyAllConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - return null; - } - - DenyAll plugin = new DenyAll(); - plugin.configure(configuration); - return plugin; - } - - public String getPluginName() - { - return DenyAll.class.getName(); - } - - public Class<DenyAll> getPluginClass() - { - return DenyAll.class; - } - }; - - @Override - public Result getDefault() - { - return Result.DENIED; - } - -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java index bd99cdd1fa..4b7a2fb457 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java @@ -18,18 +18,19 @@ */ package org.apache.qpid.server.security.access.plugins; -import java.util.Arrays; -import java.util.List; - 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.VirtualHostConfiguration; -import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.SecurityPluginFactory; -/** Always Abstain. */ +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 { @@ -37,9 +38,7 @@ public class LegacyAccess extends BasicPlugin { public List<String> getParentPaths() { - return Arrays.asList("security.jmx", "virtualhosts.virtualhost.security.jmx", - "security.msg-auth", "virtualhosts.virtualhost.security.msg-auth", - "security.principal-databases", "virtualhosts.virtualhost.security.principal-databases"); + return Arrays.asList("security.msg-auth", "virtualhosts.virtualhost.security.msg-auth"); } public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java index 8c2d60a660..949c0f2b89 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java @@ -53,8 +53,8 @@ public class AuthenticationResult ERROR } - public final AuthenticationStatus _status; - public final byte[] _challenge; + private final AuthenticationStatus _status; + private final byte[] _challenge; private final Exception _cause; private final Subject _subject; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java new file mode 100644 index 0000000000..7088fae50c --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java @@ -0,0 +1,484 @@ +/* + * + * 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.database; + +import org.apache.log4j.Logger; +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; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; +import java.security.Principal; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.locks.ReentrantLock; +import java.util.regex.Pattern; + +public abstract class AbstractPasswordFilePrincipalDatabase<U extends PasswordPrincipal> implements PrincipalDatabase +{ + private final Pattern _regexp = Pattern.compile(":"); + + private final Map<String, AuthenticationProviderInitialiser> _saslServers = + new HashMap<String, AuthenticationProviderInitialiser>(); + + protected static final String DEFAULT_ENCODING = "utf-8"; + private final Map<String, U> _userMap = new HashMap<String, U>(); + private final ReentrantLock _userUpdate = new ReentrantLock(); + private final Random _random = new Random(); + private File _passwordFile; + + + protected AbstractPasswordFilePrincipalDatabase(UsernamePasswordInitialiser... initialisers) + { + for(UsernamePasswordInitialiser initialiser : initialisers) + { + initialiser.initialise(this); + _saslServers.put(initialiser.getMechanismName(), initialiser); + } + } + + public final void setPasswordFile(String passwordFile) throws IOException + { + File f = new File(passwordFile); + getLogger().info("PasswordFile using file " + f.getAbsolutePath()); + _passwordFile = f; + if (!f.exists()) + { + throw new FileNotFoundException("Cannot find password file " + f); + } + if (!f.canRead()) + { + throw new FileNotFoundException("Cannot read password file " + f + + ". Check permissions."); + } + + loadPasswordFile(); + } + + /** + * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile + * If you want to change the password for a user, use updatePassword instead. + * + * @param principal The Principal to set the password for + * @param callback The PasswordCallback to call setPassword on + * + * @throws javax.security.auth.login.AccountNotFoundException If the Principal cannot be found in this Database + */ + public final void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException + { + if (_passwordFile == null) + { + throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation"); + } + if (principal == null) + { + throw new IllegalArgumentException("principal must not be null"); + } + char[] pwd = lookupPassword(principal.getName()); + + if (pwd != null) + { + callback.setPassword(pwd); + } + else + { + throw new AccountNotFoundException("No account found for principal " + principal); + } + } + + + /** + * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it + * creates strings of passwords. It should be modified to create only char arrays which get nulled out. + * + * @param name The principal name to lookup + * + * @return a char[] for use in SASL. + */ + protected final char[] lookupPassword(String name) + { + U user = _userMap.get(name); + if (user == null) + { + return null; + } + else + { + return user.getPassword(); + } + } + + protected boolean compareCharArray(char[] a, char[] b) + { + boolean equal = false; + if (a.length == b.length) + { + equal = true; + int index = 0; + while (equal && index < a.length) + { + equal = a[index] == b[index]; + index++; + } + } + return equal; + } + + /** + * Changes the password for the specified user + * + * @param principal to change the password for + * @param password plaintext password to set the password too + */ + public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException + { + U user = _userMap.get(principal.getName()); + + if (user == null) + { + throw new AccountNotFoundException(principal.getName()); + } + + char[] orig = user.getPassword(); + _userUpdate.lock(); + try + { + user.setPassword(password); + + savePasswordFile(); + + return true; + } + catch (IOException e) + { + getLogger().error("Unable to save password file due to '" + e.getMessage() + + "', password change for user '" + principal + "' discarded"); + //revert the password change + user.restorePassword(orig); + + return false; + } + finally + { + _userUpdate.unlock(); + } + } + + + private void loadPasswordFile() throws IOException + { + try + { + _userUpdate.lock(); + _userMap.clear(); + + BufferedReader reader = null; + try + { + reader = new BufferedReader(new FileReader(_passwordFile)); + String line; + + while ((line = reader.readLine()) != null) + { + String[] result = _regexp.split(line); + if (result == null || result.length < 2 || result[0].startsWith("#")) + { + continue; + } + + U user = createUserFromFileData(result); + getLogger().info("Created user:" + user); + _userMap.put(user.getName(), user); + } + } + finally + { + if (reader != null) + { + reader.close(); + } + } + } + finally + { + _userUpdate.unlock(); + } + } + + protected abstract U createUserFromFileData(String[] result); + + + protected abstract Logger getLogger(); + + protected File createTempFileOnSameFilesystem() + { + File liveFile = _passwordFile; + File tmp; + + do + { + tmp = new File(liveFile.getPath() + _random.nextInt() + ".tmp"); + } + while(tmp.exists()); + + tmp.deleteOnExit(); + return tmp; + } + + protected void swapTempFileToLive(final File temp) throws IOException + { + File live = _passwordFile; + // Remove any existing ".old" file + final File old = new File(live.getAbsoluteFile() + ".old"); + if (old.exists()) + { + old.delete(); + } + + // Create an new ".old" file + if(!live.renameTo(old)) + { + //unable to rename the existing file to the backup name + getLogger().error("Could not backup the existing password file"); + throw new IOException("Could not backup the existing password file"); + } + + // Move temp file to be the new "live" file + if(!temp.renameTo(live)) + { + //failed to rename the new file to the required filename + if(!old.renameTo(live)) + { + //unable to return the backup to required filename + getLogger().error( + "Could not rename the new password file into place, and unable to restore original file"); + throw new IOException("Could not rename the new password file into place, and unable to restore original file"); + } + + getLogger().error("Could not rename the new password file into place"); + throw new IOException("Could not rename the new password file into place"); + } + } + + protected void savePasswordFile() throws IOException + { + try + { + _userUpdate.lock(); + + BufferedReader reader = null; + PrintStream writer = null; + + File tmp = createTempFileOnSameFilesystem(); + + try + { + writer = new PrintStream(tmp); + reader = new BufferedReader(new FileReader(_passwordFile)); + String line; + + while ((line = reader.readLine()) != null) + { + String[] result = _regexp.split(line); + if (result == null || result.length < 2 || result[0].startsWith("#")) + { + writer.write(line.getBytes(DEFAULT_ENCODING)); + writer.println(); + continue; + } + + U user = _userMap.get(result[0]); + + if (user == null) + { + writer.write(line.getBytes(DEFAULT_ENCODING)); + writer.println(); + } + else if (!user.isDeleted()) + { + if (!user.isModified()) + { + writer.write(line.getBytes(DEFAULT_ENCODING)); + writer.println(); + } + else + { + byte[] encodedPassword = user.getEncodedPassword(); + + writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); + writer.write(encodedPassword); + writer.println(); + + user.saved(); + } + } + } + + for (U user : _userMap.values()) + { + if (user.isModified()) + { + byte[] encodedPassword; + encodedPassword = user.getEncodedPassword(); + writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); + writer.write(encodedPassword); + writer.println(); + user.saved(); + } + } + } + catch(IOException e) + { + getLogger().error("Unable to create the new password file: " + e); + throw new IOException("Unable to create the new password file",e); + } + finally + { + + try + { + if (reader != null) + { + reader.close(); + } + } + finally + { + if (writer != null) + { + writer.close(); + } + } + + } + + swapTempFileToLive(tmp); + } + finally + { + _userUpdate.unlock(); + } + } + + protected abstract U createUserFromPassword(Principal principal, char[] passwd); + + + public void reload() throws IOException + { + loadPasswordFile(); + } + + public Map<String, AuthenticationProviderInitialiser> getMechanisms() + { + return _saslServers; + } + + public List<Principal> getUsers() + { + return new LinkedList<Principal>(_userMap.values()); + } + + public Principal getUser(String username) + { + if (_userMap.containsKey(username)) + { + return new UsernamePrincipal(username); + } + return null; + } + + public boolean deletePrincipal(Principal principal) throws AccountNotFoundException + { + U user = _userMap.get(principal.getName()); + + if (user == null) + { + throw new AccountNotFoundException(principal.getName()); + } + + try + { + _userUpdate.lock(); + user.delete(); + + try + { + savePasswordFile(); + } + catch (IOException e) + { + getLogger().error("Unable to remove user '" + user.getName() + "' from password file."); + return false; + } + + _userMap.remove(user.getName()); + } + finally + { + _userUpdate.unlock(); + } + + return true; + } + + public boolean createPrincipal(Principal principal, char[] password) + { + if (_userMap.get(principal.getName()) != null) + { + return false; + } + + U user = createUserFromPassword(principal, password); + + + try + { + _userUpdate.lock(); + _userMap.put(user.getName(), user); + + try + { + savePasswordFile(); + return true; + } + catch (IOException e) + { + //remove the use on failure. + _userMap.remove(user.getName()); + return false; + } + } + finally + { + _userUpdate.unlock(); + } + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java index 5a92b33e43..63eb768035 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java @@ -21,29 +21,12 @@ package org.apache.qpid.server.security.auth.database; import org.apache.log4j.Logger; -import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean; -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.sasl.crammd5.CRAMMD5HexInitialiser; + import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser; -import org.apache.qpid.util.FileUtils; +import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser; -import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintStream; import java.security.Principal; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.locks.ReentrantLock; -import java.util.regex.Pattern; /** * Represents a user database where the account information is stored in a simple flat file. @@ -52,100 +35,19 @@ import java.util.regex.Pattern; * * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text. */ -public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase +public class Base64MD5PasswordFilePrincipalDatabase extends AbstractPasswordFilePrincipalDatabase<HashedUser> { - private static final Logger _logger = Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class); - - private File _passwordFile; - - private Pattern _regexp = Pattern.compile(":"); - - private Map<String, AuthenticationProviderInitialiser> _saslServers; - - AMQUserManagementMBean _mbean; - public static final String DEFAULT_ENCODING = "utf-8"; - private Map<String, HashedUser> _users = new HashMap<String, HashedUser>(); - private ReentrantLock _userUpdate = new ReentrantLock(); + private final Logger _logger = Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class); public Base64MD5PasswordFilePrincipalDatabase() { - _saslServers = new HashMap<String, AuthenticationProviderInitialiser>(); - /** * Create Authenticators for MD5 Password file. */ + super(new CRAMMD5HashedInitialiser(), new CRAMMD5HexInitialiser()); - // Accept Plain incomming and hash it for comparison to the file. - CRAMMD5HashedInitialiser cram = new CRAMMD5HashedInitialiser(); - cram.initialise(this); - _saslServers.put(cram.getMechanismName(), cram); - - //Add the Hex initialiser - CRAMMD5HexInitialiser cramHex = new CRAMMD5HexInitialiser(); - cramHex.initialise(this); - _saslServers.put(cramHex.getMechanismName(), cramHex); - - //fixme The PDs should setup a PD Mangement MBean -// try -// { -// _mbean = new AMQUserManagementMBean(); -// _mbean.setPrincipalDatabase(this); -// } -// catch (JMException e) -// { -// _logger.warn("User management disabled as unable to create MBean:" + e); -// } - } - - public void setPasswordFile(String passwordFile) throws IOException - { - File f = new File(passwordFile); - _logger.info("PasswordFilePrincipalDatabase using file " + f.getAbsolutePath()); - _passwordFile = f; - if (!f.exists()) - { - throw new FileNotFoundException("Cannot find password file " + f); - } - if (!f.canRead()) - { - throw new FileNotFoundException("Cannot read password file " + f + - ". Check permissions."); - } - - loadPasswordFile(); } - /** - * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile - * If you want to change the password for a user, use updatePassword instead. - * - * @param principal The Principal to set the password for - * @param callback The PasswordCallback to call setPassword on - * - * @throws AccountNotFoundException If the Principal cannont be found in this Database - */ - public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException - { - if (_passwordFile == null) - { - throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation"); - } - if (principal == null) - { - throw new IllegalArgumentException("principal must not be null"); - } - - char[] pwd = lookupPassword(principal.getName()); - - if (pwd != null) - { - callback.setPassword(pwd); - } - else - { - throw new AccountNotFoundException("No account found for principal " + principal); - } - } /** * Used to verify that the presented Password is correct. Currently only used by Management Console @@ -180,7 +82,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase } catch (Exception e1) { - _logger.warn("Unable to hash password for user '" + principal + "' for comparison"); + getLogger().warn("Unable to hash password for user '" + principal + "' for comparison"); return false; } @@ -194,374 +96,21 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase return compareCharArray(pwd, hashedPassword); } - - private boolean compareCharArray(char[] a, char[] b) - { - boolean equal = false; - if (a.length == b.length) - { - equal = true; - int index = 0; - while (equal && index < a.length) - { - equal = a[index] == b[index]; - index++; - } - } - return equal; - } - /** - * Changes the password for the specified user - * - * @param principal to change the password for - * @param password plaintext password to set the password too - */ - public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException + protected HashedUser createUserFromPassword(Principal principal, char[] passwd) { - HashedUser user = _users.get(principal.getName()); - - if (user == null) - { - throw new AccountNotFoundException(principal.getName()); - } - - try - { - try - { - _userUpdate.lock(); - char[] orig = user.getPassword(); - user.setPassword(password,false); - - try - { - savePasswordFile(); - } - catch (IOException e) - { - _logger.error("Unable to save password file, password change for user'" - + principal + "' will revert at restart"); - //revert the password change - user.setPassword(orig,true); - return false; - } - return true; - } - finally - { - _userUpdate.unlock(); - } - } - catch (Exception e) - { - return false; - } + return new HashedUser(principal.getName(), passwd); } - public boolean createPrincipal(Principal principal, char[] password) - { - if (_users.get(principal.getName()) != null) - { - return false; - } - HashedUser user; - try - { - user = new HashedUser(principal.getName(), password); - } - catch (Exception e1) - { - _logger.warn("Unable to create new user '" + principal.getName() + "'"); - return false; - } - - - try - { - _userUpdate.lock(); - _users.put(user.getName(), user); - - try - { - savePasswordFile(); - return true; - } - catch (IOException e) - { - //remove the use on failure. - _users.remove(user.getName()); - return false; - } - } - finally - { - _userUpdate.unlock(); - } - } - - public boolean deletePrincipal(Principal principal) throws AccountNotFoundException - { - HashedUser user = _users.get(principal.getName()); - - if (user == null) - { - throw new AccountNotFoundException(principal.getName()); - } - - try - { - _userUpdate.lock(); - user.delete(); - - try - { - savePasswordFile(); - } - catch (IOException e) - { - _logger.warn("Unable to remove user '" + user.getName() + "' from password file."); - return false; - } - - _users.remove(user.getName()); - } - finally - { - _userUpdate.unlock(); - } - - return true; - } - - public Map<String, AuthenticationProviderInitialiser> getMechanisms() - { - return _saslServers; - } - - public List<Principal> getUsers() - { - return new LinkedList<Principal>(_users.values()); - } - - public Principal getUser(String username) - { - if (_users.containsKey(username)) - { - return new UsernamePrincipal(username); - } - return null; - } - - /** - * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it - * creates strings of passwords. It should be modified to create only char arrays which get nulled out. - * - * @param name The principal name to lookup - * - * @return a char[] for use in SASL. - */ - private char[] lookupPassword(String name) + protected HashedUser createUserFromFileData(String[] result) { - HashedUser user = _users.get(name); - if (user == null) - { - return null; - } - else - { - return user.getPassword(); - } - } - - private void loadPasswordFile() throws IOException - { - try - { - _userUpdate.lock(); - _users.clear(); - - BufferedReader reader = null; - try - { - reader = new BufferedReader(new FileReader(_passwordFile)); - String line; - - while ((line = reader.readLine()) != null) - { - String[] result = _regexp.split(line); - if (result == null || result.length < 2 || result[0].startsWith("#")) - { - continue; - } - - HashedUser user = new HashedUser(result); - _logger.info("Created user:" + user); - _users.put(user.getName(), user); - } - } - finally - { - if (reader != null) - { - reader.close(); - } - } - } - finally - { - _userUpdate.unlock(); - } - } - - private void savePasswordFile() throws IOException - { - try - { - _userUpdate.lock(); - - BufferedReader reader = null; - PrintStream writer = null; - - Random r = new Random(); - File tmp; - do - { - tmp = new File(_passwordFile.getPath() + r.nextInt() + ".tmp"); - } - while(tmp.exists()); - - tmp.deleteOnExit(); - - try - { - writer = new PrintStream(tmp); - reader = new BufferedReader(new FileReader(_passwordFile)); - String line; - - while ((line = reader.readLine()) != null) - { - String[] result = _regexp.split(line); - if (result == null || result.length < 2 || result[0].startsWith("#")) - { - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - continue; - } - - HashedUser user = _users.get(result[0]); - - if (user == null) - { - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - } - else if (!user.isDeleted()) - { - if (!user.isModified()) - { - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - } - else - { - try - { - byte[] encodedPassword = user.getEncodedPassword(); - - writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); - writer.write(encodedPassword); - writer.println(); - - user.saved(); - } - catch (Exception e) - { - _logger.warn("Unable to encode new password reverting to old password."); - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - } - } - } - } - - for (HashedUser user : _users.values()) - { - if (user.isModified()) - { - byte[] encodedPassword; - try - { - encodedPassword = user.getEncodedPassword(); - writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); - writer.write(encodedPassword); - writer.println(); - user.saved(); - } - catch (Exception e) - { - _logger.warn("Unable to get Encoded password for user'" + user.getName() + "' password not saved"); - } - } - } - } - catch(IOException e) - { - _logger.error("Unable to create the new password file: " + e); - throw new IOException("Unable to create the new password file" + e); - } - finally - { - if (reader != null) - { - reader.close(); - } - - if (writer != null) - { - writer.close(); - } - } - - // Swap temp file to main password file. - File old = new File(_passwordFile.getAbsoluteFile() + ".old"); - if (old.exists()) - { - old.delete(); - } - - if(!_passwordFile.renameTo(old)) - { - //unable to rename the existing file to the backup name - _logger.error("Could not backup the existing password file"); - throw new IOException("Could not backup the existing password file"); - } - - if(!tmp.renameTo(_passwordFile)) - { - //failed to rename the new file to the required filename - - if(!old.renameTo(_passwordFile)) - { - //unable to return the backup to required filename - _logger.error("Could not rename the new password file into place, and unable to restore original file"); - throw new IOException("Could not rename the new password file into place, and unable to restore original file"); - } - - _logger.error("Could not rename the new password file into place"); - throw new IOException("Could not rename the new password file into place"); - } - } - finally - { - _userUpdate.unlock(); - } + return new HashedUser(result); } - public void reload() throws IOException + protected Logger getLogger() { - loadPasswordFile(); + return _logger; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java index 3690e7f92a..b9de1587b5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java @@ -20,26 +20,25 @@ */ package org.apache.qpid.server.security.auth.database; -import org.apache.commons.codec.EncoderException; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.Principal; -public class HashedUser implements Principal + +public class HashedUser implements PasswordPrincipal { private static final Logger _logger = Logger.getLogger(HashedUser.class); - String _name; - char[] _password; - byte[] _encodedPassword = null; + private String _name; + private char[] _password; + private byte[] _encodedPassword = null; private boolean _modified = false; private boolean _deleted = false; - HashedUser(String[] data) throws UnsupportedEncodingException + HashedUser(String[] data) { if (data.length != 2) { @@ -48,7 +47,15 @@ public class HashedUser implements Principal _name = data[0]; - byte[] encoded_password = data[1].getBytes(Base64MD5PasswordFilePrincipalDatabase.DEFAULT_ENCODING); + byte[] encoded_password; + try + { + encoded_password = data[1].getBytes(Base64MD5PasswordFilePrincipalDatabase.DEFAULT_ENCODING); + } + catch (UnsupportedEncodingException e) + { + throw new RuntimeException("MD5 encoding not supported, even though the Java standard requires it",e); + } Base64 b64 = new Base64(); byte[] decoded = b64.decode(encoded_password); @@ -64,15 +71,23 @@ public class HashedUser implements Principal } } - public HashedUser(String name, char[] password) throws UnsupportedEncodingException, NoSuchAlgorithmException + public HashedUser(String name, char[] password) { _name = name; setPassword(password,false); } - public static byte[] getMD5(byte[] data) throws NoSuchAlgorithmException, UnsupportedEncodingException + public static byte[] getMD5(byte[] data) { - MessageDigest md = MessageDigest.getInstance("MD5"); + MessageDigest md = null; + try + { + md = MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException e) + { + throw new RuntimeException("MD5 not supported although Java compliance requires it"); + } for (byte b : data) { @@ -92,12 +107,22 @@ public class HashedUser implements Principal return _name; } - char[] getPassword() + public char[] getPassword() { return _password; } - void setPassword(char[] password, boolean alreadyHashed) throws UnsupportedEncodingException, NoSuchAlgorithmException + public void setPassword(char[] password) + { + setPassword(password, false); + } + + public void restorePassword(char[] password) + { + setPassword(password, true); + } + + void setPassword(char[] password, boolean alreadyHashed) { if(alreadyHashed){ _password = password; @@ -126,7 +151,7 @@ public class HashedUser implements Principal _encodedPassword = null; } - byte[] getEncodedPassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException + public byte[] getEncodedPassword() { if (_encodedPassword == null) { @@ -135,7 +160,7 @@ public class HashedUser implements Principal return _encodedPassword; } - private void encodePassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException + private void encodePassword() { byte[] byteArray = new byte[_password.length]; int index = 0; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/MessageRouter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PasswordPrincipal.java index 025a8014aa..8e12d5f0a3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/MessageRouter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PasswordPrincipal.java @@ -18,23 +18,23 @@ * under the License. * */ -package org.apache.qpid.server.exchange; +package org.apache.qpid.server.security.auth.database; -import org.apache.qpid.AMQException; -import org.apache.qpid.server.queue.IncomingMessage; +import java.security.Principal; -/** - * Separated out from the ExchangeRegistry interface to allow components - * that use only this part to have a dependency with a reduced footprint. - * - */ -public interface MessageRouter +interface PasswordPrincipal extends Principal { - /** - * Routes content through exchanges, delivering it to 1 or more queues. - * @param message the message to be routed - * - * @throws org.apache.qpid.AMQException if something goes wrong delivering data - */ - void routeContent(IncomingMessage message) throws AMQException; + char[] getPassword(); + byte[] getEncodedPassword(); + + void setPassword(char[] password); + void restorePassword(char[] password); + + boolean isDeleted(); + + boolean isModified(); + + void saved(); + + void delete(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java index 7cb34da804..bfd04adb3f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java @@ -21,29 +21,13 @@ package org.apache.qpid.server.security.auth.database; import org.apache.log4j.Logger; -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.sasl.amqplain.AmqPlainInitialiser; -import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousInitialiser; 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.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintStream; import java.security.Principal; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.locks.ReentrantLock; -import java.util.regex.Pattern; /** * Represents a user database where the account information is stored in a simple flat file. @@ -52,102 +36,19 @@ import java.util.regex.Pattern; * * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text. */ -public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase +public class PlainPasswordFilePrincipalDatabase extends AbstractPasswordFilePrincipalDatabase<PlainUser> { - public static final String DEFAULT_ENCODING = "utf-8"; - - private static final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class); - - private File _passwordFile; - - private Pattern _regexp = Pattern.compile(":"); - private Map<String, AuthenticationProviderInitialiser> _saslServers; - - private Map<String, PlainUser> _users = new HashMap<String, PlainUser>(); - private ReentrantLock _userUpdate = new ReentrantLock(); + private final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class); public PlainPasswordFilePrincipalDatabase() { - _saslServers = new HashMap<String, AuthenticationProviderInitialiser>(); - /** * Create Authenticators for Plain Password file. */ - - // Accept AMQPlain incomming and compare it to the file. - AmqPlainInitialiser amqplain = new AmqPlainInitialiser(); - amqplain.initialise(this); - - - - // Accept AMQPlain incomming and compare it to the file. - AnonymousInitialiser anonymous = new AnonymousInitialiser(); - anonymous.initialise(this); - - - // Accept Plain incomming and compare it to the file. - PlainInitialiser plain = new PlainInitialiser(); - plain.initialise(this); - - // Accept MD5 incomming and Hash file value for comparison - CRAMMD5Initialiser cram = new CRAMMD5Initialiser(); - cram.initialise(this); - - _saslServers.put(amqplain.getMechanismName(), amqplain); - _saslServers.put(plain.getMechanismName(), plain); - _saslServers.put(cram.getMechanismName(), cram); - _saslServers.put(anonymous.getMechanismName(), anonymous); - } - - public void setPasswordFile(String passwordFile) throws IOException - { - File f = new File(passwordFile); - _logger.info("PlainPasswordFile using file " + f.getAbsolutePath()); - _passwordFile = f; - if (!f.exists()) - { - throw new FileNotFoundException("Cannot find password file " + f); - } - if (!f.canRead()) - { - throw new FileNotFoundException("Cannot read password file " + f + - ". Check permissions."); - } - - loadPasswordFile(); + super(new AmqPlainInitialiser(), new PlainInitialiser(), new CRAMMD5Initialiser()); } - /** - * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile - * If you want to change the password for a user, use updatePassword instead. - * - * @param principal The Principal to set the password for - * @param callback The PasswordCallback to call setPassword on - * - * @throws AccountNotFoundException If the Principal cannot be found in this Database - */ - public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException - { - if (_passwordFile == null) - { - throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation"); - } - if (principal == null) - { - throw new IllegalArgumentException("principal must not be null"); - } - char[] pwd = lookupPassword(principal.getName()); - - if (pwd != null) - { - callback.setPassword(pwd); - } - else - { - throw new AccountNotFoundException("No account found for principal " + principal); - } - } /** * Used to verify that the presented Password is correct. Currently only used by Management Console @@ -173,352 +74,21 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase } - /** - * Changes the password for the specified user - * - * @param principal to change the password for - * @param password plaintext password to set the password too - */ - public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException + protected PlainUser createUserFromPassword(Principal principal, char[] passwd) { - PlainUser user = _users.get(principal.getName()); - - if (user == null) - { - throw new AccountNotFoundException(principal.getName()); - } - - char[] orig = user.getPassword(); - _userUpdate.lock(); - try - { - user.setPassword(password); - - savePasswordFile(); - - return true; - } - catch (IOException e) - { - _logger.error("Unable to save password file due to '"+e.getMessage() - +"', password change for user '" + principal + "' discarded"); - //revert the password change - user.setPassword(orig); - return false; - } - finally - { - _userUpdate.unlock(); - } + return new PlainUser(principal.getName(), passwd); } - public boolean createPrincipal(Principal principal, char[] password) - { - if (_users.get(principal.getName()) != null) - { - return false; - } - - PlainUser user = new PlainUser(principal.getName(), password); - - try - { - _userUpdate.lock(); - _users.put(user.getName(), user); - - try - { - savePasswordFile(); - return true; - } - catch (IOException e) - { - //remove the use on failure. - _users.remove(user.getName()); - _logger.warn("Unable to create user '" + user.getName()); - return false; - } - } - finally - { - _userUpdate.unlock(); - } - } - public boolean deletePrincipal(Principal principal) throws AccountNotFoundException + @Override + protected PlainUser createUserFromFileData(String[] result) { - PlainUser user = _users.get(principal.getName()); - - if (user == null) - { - throw new AccountNotFoundException(principal.getName()); - } - - try - { - _userUpdate.lock(); - user.delete(); - - try - { - savePasswordFile(); - } - catch (IOException e) - { - _logger.error("Unable to remove user '" + user.getName() + "' from password file."); - return false; - } - - _users.remove(user.getName()); - } - finally - { - _userUpdate.unlock(); - } - - return true; + return new PlainUser(result); } - public Map<String, AuthenticationProviderInitialiser> getMechanisms() - { - return _saslServers; - } - public List<Principal> getUsers() - { - return new LinkedList<Principal>(_users.values()); - } - - public Principal getUser(String username) - { - if (_users.containsKey(username)) - { - return new UsernamePrincipal(username); - } - return null; - } - - private boolean compareCharArray(char[] a, char[] b) - { - boolean equal = false; - if (a.length == b.length) - { - equal = true; - int index = 0; - while (equal && index < a.length) - { - equal = a[index] == b[index]; - index++; - } - } - return equal; - } - - - /** - * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it - * creates strings of passwords. It should be modified to create only char arrays which get nulled out. - * - * @param name The principal name to lookup - * - * @return a char[] for use in SASL. - */ - private char[] lookupPassword(String name) - { - PlainUser user = _users.get(name); - if (user == null) - { - return null; - } - else - { - return user.getPassword(); - } - } - - private void loadPasswordFile() throws IOException - { - try - { - _userUpdate.lock(); - _users.clear(); - - BufferedReader reader = null; - try - { - reader = new BufferedReader(new FileReader(_passwordFile)); - String line; - - while ((line = reader.readLine()) != null) - { - String[] result = _regexp.split(line); - if (result == null || result.length < 2 || result[0].startsWith("#")) - { - continue; - } - - PlainUser user = new PlainUser(result); - _logger.info("Created user:" + user); - _users.put(user.getName(), user); - } - } - finally - { - if (reader != null) - { - reader.close(); - } - } - } - finally - { - _userUpdate.unlock(); - } - } - - private void savePasswordFile() throws IOException - { - try - { - _userUpdate.lock(); - - BufferedReader reader = null; - PrintStream writer = null; - - final File tmp = createTempFileOnSameFilesystem(_passwordFile); - - try - { - writer = new PrintStream(tmp); - reader = new BufferedReader(new FileReader(_passwordFile)); - String line; - - while ((line = reader.readLine()) != null) - { - String[] result = _regexp.split(line); - if (result == null || result.length < 2 || result[0].startsWith("#")) - { - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - continue; - } - - PlainUser user = _users.get(result[0]); - - if (user == null) - { - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - } - else if (!user.isDeleted()) - { - if (!user.isModified()) - { - writer.write(line.getBytes(DEFAULT_ENCODING)); - writer.println(); - } - else - { - byte[] password = user.getPasswordBytes(); - - writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); - writer.write(password); - writer.println(); - - user.saved(); - } - } - } - - for (PlainUser user : _users.values()) - { - if (user.isModified()) - { - byte[] password; - password = user.getPasswordBytes(); - writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING)); - writer.write(password); - writer.println(); - user.saved(); - } - } - } - catch(IOException e) - { - _logger.error("Unable to create the new password file: " + e); - throw new IOException("Unable to create the new password file" + e); - } - finally - { - if (writer != null) - { - writer.close(); - } - if (reader != null) - { - reader.close(); - } - } - - swapTempFileToLive(_passwordFile, tmp); - - } - finally - { - _userUpdate.unlock(); - } - } - - private void swapTempFileToLive(final File live, final File temp) throws IOException - { - // Remove any existing ".old" file - final File old = new File(live.getAbsoluteFile() + ".old"); - if (old.exists()) - { - old.delete(); - } - - // Create an new ".old" file - if(!live.renameTo(old)) - { - //unable to rename the existing file to the backup name - _logger.error("Could not backup the existing password file"); - throw new IOException("Could not backup the existing password file"); - } - - // Move temp file to be the new "live" file - if(!temp.renameTo(live)) - { - //failed to rename the new file to the required filename - if(!old.renameTo(live)) - { - //unable to return the backup to required filename - _logger.error("Could not rename the new password file into place, and unable to restore original file"); - throw new IOException("Could not rename the new password file into place, and unable to restore original file"); - } - - _logger.error("Could not rename the new password file into place"); - throw new IOException("Could not rename the new password file into place"); - } - } - - private File createTempFileOnSameFilesystem(final File liveFile) - { - File tmp; - final Random r = new Random(); - - do - { - tmp = new File(liveFile.getPath() + r.nextInt() + ".tmp"); - } - while(tmp.exists()); - - tmp.deleteOnExit(); - return tmp; - } - - public void reload() throws IOException + protected Logger getLogger() { - loadPasswordFile(); + return _logger; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java index 46a78a55aa..bf9bfc6c99 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java @@ -20,11 +20,7 @@ */ package org.apache.qpid.server.security.auth.database; -import org.apache.log4j.Logger; - -import java.security.Principal; - -public class PlainUser implements Principal +public class PlainUser implements PasswordPrincipal { private String _name; private char[] _password; @@ -61,12 +57,12 @@ public class PlainUser implements Principal return _name; } - char[] getPassword() + public char[] getPassword() { return _password; } - byte[] getPasswordBytes() + public byte[] getEncodedPassword() { byte[] byteArray = new byte[_password.length]; int index = 0; @@ -77,7 +73,14 @@ public class PlainUser implements Principal return byteArray; } - void setPassword(char[] password) + + + public void restorePassword(char[] password) + { + setPassword(password); + } + + public void setPassword(char[] password) { _password = password; _modified = true; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java index ef37e043a6..67f4b7344a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java @@ -22,14 +22,12 @@ package org.apache.qpid.server.security.auth.database; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; +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.Map; import java.util.List; - -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.login.AccountNotFoundException; +import java.util.Map; /** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */ public interface PrincipalDatabase diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java index ff8851306f..4203cb0e07 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java @@ -27,14 +27,14 @@ import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; -import java.util.Properties; -import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.LinkedList; -import java.security.Principal; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; public class PropertiesPrincipalDatabase implements PrincipalDatabase { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java index 208130379e..1314a5d6a6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java @@ -20,9 +20,14 @@ */ package org.apache.qpid.server.security.auth.management; -import java.io.IOException; -import java.security.Principal; -import java.util.List; +import org.apache.log4j.Logger; + +import org.apache.qpid.management.common.mbeans.UserManagement; +import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; +import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; +import org.apache.qpid.server.management.AMQManagedObject; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; +import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import javax.management.JMException; import javax.management.openmbean.CompositeData; @@ -35,14 +40,9 @@ import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; import javax.security.auth.login.AccountNotFoundException; - -import org.apache.log4j.Logger; -import org.apache.qpid.management.common.mbeans.UserManagement; -import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; -import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation; -import org.apache.qpid.server.management.AMQManagedObject; -import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import java.io.IOException; +import java.security.Principal; +import java.util.List; /** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */ @MBeanDescription("User Management Interface") diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java index 82eb7d3621..03cc12d06c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java @@ -20,21 +20,20 @@ */ package org.apache.qpid.server.security.auth.manager; -import javax.security.auth.Subject; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; - import org.apache.qpid.amqp_1_0.transport.CallbackHanderSource; import org.apache.qpid.common.Closeable; import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.auth.AuthenticationResult; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + /** * 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 Subject} containing the user's identity and zero or more principals representing + * {@link javax.security.auth.Subject} containing the user's identity and zero or more principals representing * groups to which the user belongs. * <p> * The {@link #initialise()} method is responsible for registering SASL mechanisms required by diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java index 978ad2b1f3..b5d70d9200 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java @@ -20,29 +20,10 @@ */ package org.apache.qpid.server.security.auth.manager; -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; - -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 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; @@ -55,6 +36,25 @@ import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialis import org.apache.qpid.server.security.auth.sasl.JCAProvider; import org.apache.qpid.server.security.auth.sasl.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; + /** * Concrete implementation of the AuthenticationManager that determines if supplied @@ -95,9 +95,9 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan */ private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>(); - protected PrincipalDatabase _principalDatabase = null; + private PrincipalDatabase _principalDatabase = null; - protected AMQUserManagementMBean _mbean = null; + private AMQUserManagementMBean _mbean = null; public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>() { @@ -160,13 +160,13 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan public String getPrincipalDatabaseClass() { - return _configuration.getString("principal-database.class"); + return getConfig().getString("principal-database.class"); } public Map<String,String> getPdClassAttributeMap() throws ConfigurationException { - final List<String> argumentNames = _configuration.getList("principal-database.attributes.attribute.name"); - final List<String> argumentValues = _configuration.getList("principal-database.attributes.attribute.value"); + final List<String> argumentNames = getConfig().getList("principal-database.attributes.attribute.name"); + final List<String> argumentValues = 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++) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java index b7985ad972..e27fd99f90 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java @@ -20,14 +20,14 @@ */ package org.apache.qpid.server.security.auth.rmi; -import javax.management.remote.JMXAuthenticator; -import javax.management.remote.JMXPrincipal; -import javax.security.auth.Subject; - 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.JMXAuthenticator; +import javax.management.remote.JMXPrincipal; +import javax.security.auth.Subject; + public class RMIPasswordAuthenticator implements JMXAuthenticator { static final String UNABLE_TO_LOOKUP = "The broker was unable to lookup the user details"; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java index bc5d8a4f2b..c227aa14e8 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java @@ -20,10 +20,9 @@ */ package org.apache.qpid.server.security.auth.sasl; -import java.util.Map; - import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslServerFactory; +import java.util.Map; public interface AuthenticationProviderInitialiser { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java index d6f6c714e2..8711e1b385 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java @@ -20,11 +20,10 @@ */ package org.apache.qpid.server.security.auth.sasl; +import javax.security.sasl.SaslServerFactory; import java.security.Provider; import java.util.Map; -import javax.security.sasl.SaslServerFactory; - public class JCAProvider extends Provider { public JCAProvider(String name, Map<String, Class<? extends SaslServerFactory>> providerMap) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java index 5c13e03886..f4e8f800c6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java @@ -20,9 +20,10 @@ */ package org.apache.qpid.server.security.auth.sasl; -import java.io.IOException; -import java.security.Principal; -import java.util.Map; +import org.apache.commons.configuration.Configuration; +import org.apache.log4j.Logger; + +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; @@ -31,14 +32,9 @@ import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.AccountNotFoundException; import javax.security.sasl.AuthorizeCallback; - -import org.apache.commons.configuration.Configuration; - -import org.apache.log4j.Logger; - -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.UsernamePrincipal; +import java.io.IOException; +import java.security.Principal; +import java.util.Map; public abstract class UsernamePasswordInitialiser implements AuthenticationProviderInitialiser { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java index b4ee13fe6b..9e7db94216 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java @@ -20,11 +20,10 @@ */ package org.apache.qpid.server.security.auth.sasl; +import javax.security.auth.Subject; import java.security.Principal; import java.util.Set; -import javax.security.auth.Subject; - /** A principal that is just a wrapper for a simple username. */ public class UsernamePrincipal implements Principal { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java index 7acc6322d1..860307215f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java @@ -20,10 +20,10 @@ */ package org.apache.qpid.server.security.auth.sasl.amqplain; -import javax.security.sasl.SaslServerFactory; - import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; +import javax.security.sasl.SaslServerFactory; + public class AmqPlainInitialiser extends UsernamePasswordInitialiser { public String getMechanismName() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java index dee40e7069..eecc704011 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java @@ -20,9 +20,9 @@ */ package org.apache.qpid.server.security.auth.sasl.amqplain; -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; +import org.apache.qpid.framing.AMQFrameDecodingException; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.FieldTableFactory; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; @@ -32,10 +32,9 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; - -import org.apache.qpid.framing.AMQFrameDecodingException; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; public class AmqPlainSaslServer implements SaslServer { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java index 17d123eb0d..3a73f577fe 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.security.auth.sasl.amqplain; -import java.util.Map; - import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; +import java.util.Map; public class AmqPlainSaslServerFactory implements SaslServerFactory { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java index e35e999766..83369a84c7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java @@ -20,53 +20,17 @@ */ package org.apache.qpid.server.security.auth.sasl.anonymous; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.sasl.SaslServerFactory; - -import org.apache.commons.configuration.Configuration; -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 java.io.IOException; -import java.util.Map; +import javax.security.sasl.SaslServerFactory; -public class AnonymousInitialiser implements AuthenticationProviderInitialiser +public class AnonymousInitialiser extends UsernamePasswordInitialiser { public String getMechanismName() { return "ANONYMOUS"; } - public void initialise(String baseConfigPath, Configuration configuration, Map<String, PrincipalDatabase> principalDatabases) throws Exception - { - } - - public void initialise(PrincipalDatabase db) - { - } - - public CallbackHandler getCallbackHandler() - { - return new CallbackHandler() - { - - public Callback[] _callbacks; - - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException - { - _callbacks =callbacks; - } - }; - } - - public Map<String, ?> getProperties() - { - return null; - } - public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration() { return AnonymousSaslServerFactory.class; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java index de695032ab..4650234972 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java @@ -20,15 +20,12 @@ */ package org.apache.qpid.server.security.auth.sasl.anonymous; -import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainSaslServer; - -import java.util.Map; - import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; +import java.util.Map; public class AnonymousSaslServerFactory implements SaslServerFactory { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java index 97f9a4e91a..842215c3eb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.security.auth.sasl.crammd5; -import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; +import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; import javax.security.sasl.SaslServerFactory; import java.util.Map; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java index f6cab084ea..a2d9fa5e3e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.security.auth.sasl.crammd5; -import javax.security.sasl.SaslServer; -import javax.security.sasl.SaslException; +import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; -import javax.security.auth.callback.CallbackHandler; import java.util.Enumeration; import java.util.Map; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java index 5298b5cc63..4e82940439 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.security.auth.sasl.crammd5; -import java.util.Map; - import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; +import java.util.Map; public class CRAMMD5HashedServerFactory implements SaslServerFactory { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java index 139818735f..478f195530 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java @@ -21,16 +21,16 @@ package org.apache.qpid.server.security.auth.sasl.crammd5; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; +import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; -import javax.security.sasl.SaslServerFactory; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; -import java.util.Map; -import java.util.List; -import java.security.Principal; +import javax.security.sasl.SaslServerFactory; import java.io.IOException; +import java.security.Principal; +import java.util.List; +import java.util.Map; public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java index 192ff74bff..e19baaa7c6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.security.auth.sasl.crammd5; -import javax.security.sasl.SaslServer; -import javax.security.sasl.SaslException; +import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; -import javax.security.auth.callback.CallbackHandler; import java.util.Enumeration; import java.util.Map; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java index ce0e19abf9..06c9108a73 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.security.auth.sasl.crammd5; -import java.util.Map; - import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; +import java.util.Map; public class CRAMMD5HexServerFactory implements SaslServerFactory { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java index 264832888d..83e33d5491 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.security.auth.sasl.crammd5; -import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; +import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; import javax.security.sasl.SaslServerFactory; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java index 1d16cd8755..67676d363e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java @@ -20,10 +20,10 @@ */ package org.apache.qpid.server.security.auth.sasl.plain; -import javax.security.sasl.SaslServerFactory; - import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; +import javax.security.sasl.SaslServerFactory; + public class PlainInitialiser extends UsernamePasswordInitialiser { public String getMechanismName() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java index 7230e8ee53..0ea2f3c92e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java @@ -20,9 +20,8 @@ */ package org.apache.qpid.server.security.auth.sasl.plain; -import java.util.Arrays; - import javax.security.auth.callback.PasswordCallback; +import java.util.Arrays; /** * Custom PasswordCallback for use during the PLAIN authentication process. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java index 847a3a34ce..a811806c00 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java @@ -20,16 +20,14 @@ */ package org.apache.qpid.server.security.auth.sasl.plain; -import java.io.IOException; - 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.AuthorizeCallback; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; +import java.io.IOException; public class PlainSaslServer implements SaslServer { @@ -53,57 +51,65 @@ public class PlainSaslServer implements SaslServer public byte[] evaluateResponse(byte[] response) throws SaslException { - try + int authzidNullPosition = findNullPosition(response, 0); + if (authzidNullPosition < 0) { - int authzidNullPosition = findNullPosition(response, 0); - if (authzidNullPosition < 0) - { - throw new SaslException("Invalid PLAIN encoding, authzid null terminator not found"); - } - int authcidNullPosition = findNullPosition(response, authzidNullPosition + 1); - if (authcidNullPosition < 0) - { - throw new SaslException("Invalid PLAIN encoding, authcid null terminator not found"); - } + throw new SaslException("Invalid PLAIN encoding, authzid null terminator not found"); + } + int authcidNullPosition = findNullPosition(response, authzidNullPosition + 1); + if (authcidNullPosition < 0) + { + throw new SaslException("Invalid PLAIN encoding, authcid null terminator not found"); + } + + PlainPasswordCallback passwordCb; + AuthorizeCallback authzCb; + try + { // we do not currently support authcid in any meaningful way - // String authcid = new String(response, 0, authzidNullPosition, "utf8"); String authzid = new String(response, authzidNullPosition + 1, authcidNullPosition - authzidNullPosition - 1, "utf8"); // TODO: should not get pwd as a String but as a char array... int passwordLen = response.length - authcidNullPosition - 1; String pwd = new String(response, authcidNullPosition + 1, passwordLen, "utf8"); - + // we do not care about the prompt but it throws if null NameCallback nameCb = new NameCallback("prompt", authzid); - PlainPasswordCallback passwordCb = new PlainPasswordCallback("prompt", false, pwd); - AuthorizeCallback authzCb = new AuthorizeCallback(authzid, authzid); + passwordCb = new PlainPasswordCallback("prompt", false, pwd); + authzCb = new AuthorizeCallback(authzid, authzid); Callback[] callbacks = new Callback[]{nameCb, passwordCb, authzCb}; _cbh.handle(callbacks); - if (passwordCb.isAuthenticated()) - { - _complete = true; - } - if (authzCb.isAuthorized() && _complete) - { - _authorizationId = authzCb.getAuthenticationID(); - return null; - } - else - { - throw new SaslException("Authentication failed"); - } } catch (IOException e) { + if(e instanceof SaslException) + { + throw (SaslException) e; + } throw new SaslException("Error processing data: " + e, e); } catch (UnsupportedCallbackException e) { throw new SaslException("Unable to obtain data from callback handler: " + e, e); } + + if (passwordCb.isAuthenticated()) + { + _complete = true; + } + + if (authzCb.isAuthorized() && _complete) + { + _authorizationId = authzCb.getAuthenticationID(); + return null; + } + else + { + throw new SaslException("Authentication failed"); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java index 3144bfbce6..445e5ef812 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.security.auth.sasl.plain; -import java.util.Map; - import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; +import java.util.Map; public class PlainSaslServerFactory implements SaslServerFactory { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java index 4e3fae1dbd..bdcfd86f82 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java @@ -20,13 +20,13 @@ */ 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; -import org.apache.log4j.Logger; - public abstract class SignalHandlerTask { private static final Logger LOGGER = Logger.getLogger(SignalHandlerTask.class); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java index 33aebffcfb..f97b77a4fe 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java @@ -20,51 +20,23 @@ */ package org.apache.qpid.server.state; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArraySet; - import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.AMQConnectionException; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.ChannelCloseBody; +import org.apache.qpid.framing.ChannelCloseOkBody; +import org.apache.qpid.framing.ChannelOpenBody; +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.protocol.AMQConstant; -import org.apache.qpid.server.handler.BasicAckMethodHandler; -import org.apache.qpid.server.handler.BasicCancelMethodHandler; -import org.apache.qpid.server.handler.BasicConsumeMethodHandler; -import org.apache.qpid.server.handler.BasicGetMethodHandler; -import org.apache.qpid.server.handler.BasicPublishMethodHandler; -import org.apache.qpid.server.handler.BasicQosHandler; -import org.apache.qpid.server.handler.BasicRecoverMethodHandler; -import org.apache.qpid.server.handler.BasicRejectMethodHandler; -import org.apache.qpid.server.handler.ChannelCloseHandler; -import org.apache.qpid.server.handler.ChannelCloseOkHandler; -import org.apache.qpid.server.handler.ChannelFlowHandler; -import org.apache.qpid.server.handler.ChannelOpenHandler; -import org.apache.qpid.server.handler.ConnectionCloseMethodHandler; -import org.apache.qpid.server.handler.ConnectionCloseOkMethodHandler; -import org.apache.qpid.server.handler.ConnectionOpenMethodHandler; -import org.apache.qpid.server.handler.ConnectionSecureOkMethodHandler; -import org.apache.qpid.server.handler.ConnectionStartOkMethodHandler; -import org.apache.qpid.server.handler.ConnectionTuneOkMethodHandler; -import org.apache.qpid.server.handler.ExchangeBoundHandler; -import org.apache.qpid.server.handler.ExchangeDeclareHandler; -import org.apache.qpid.server.handler.ExchangeDeleteHandler; -import org.apache.qpid.server.handler.QueueBindHandler; -import org.apache.qpid.server.handler.QueueDeclareHandler; -import org.apache.qpid.server.handler.QueueDeleteHandler; -import org.apache.qpid.server.handler.QueuePurgeHandler; -import org.apache.qpid.server.handler.TxCommitHandler; -import org.apache.qpid.server.handler.TxRollbackHandler; -import org.apache.qpid.server.handler.TxSelectHandler; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; +import java.util.concurrent.CopyOnWriteArraySet; + /** * The state manager is responsible for managing the state of the protocol session. <p/> For each AMQProtocolHandler * there is a separate state manager. @@ -78,16 +50,6 @@ public class AMQStateManager implements AMQMethodListener /** The current state */ private AMQState _currentState; - /** - * Maps from an AMQState instance to a Map from Class to StateTransitionHandler. The class must be a subclass of - * AMQFrame. - */ -/* private final EnumMap<AMQState, Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>> _state2HandlersMap = - new EnumMap<AMQState, Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>>( - AMQState.class); - */ - - private CopyOnWriteArraySet<StateListener> _stateListeners = new CopyOnWriteArraySet<StateListener>(); public AMQStateManager(VirtualHostRegistry virtualHostRegistry, AMQProtocolSession protocolSession) @@ -99,64 +61,6 @@ public class AMQStateManager implements AMQMethodListener } - /* - protected void registerListeners() - { - Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>> frame2handlerMap; - - frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_STARTED, frame2handlerMap); - - frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_AUTH, frame2handlerMap); - - frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_TUNED, frame2handlerMap); - - frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - frame2handlerMap.put(ConnectionOpenBody.class, ConnectionOpenMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_OPENED, frame2handlerMap); - - // - // ConnectionOpen handlers - // - frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - ChannelOpenHandler.getInstance(); - ChannelCloseHandler.getInstance(); - ChannelCloseOkHandler.getInstance(); - ConnectionCloseMethodHandler.getInstance(); - ConnectionCloseOkMethodHandler.getInstance(); - ConnectionTuneOkMethodHandler.getInstance(); - ConnectionSecureOkMethodHandler.getInstance(); - ConnectionStartOkMethodHandler.getInstance(); - ExchangeDeclareHandler.getInstance(); - ExchangeDeleteHandler.getInstance(); - ExchangeBoundHandler.getInstance(); - BasicAckMethodHandler.getInstance(); - BasicRecoverMethodHandler.getInstance(); - BasicConsumeMethodHandler.getInstance(); - BasicGetMethodHandler.getInstance(); - BasicCancelMethodHandler.getInstance(); - BasicPublishMethodHandler.getInstance(); - BasicQosHandler.getInstance(); - QueueBindHandler.getInstance(); - QueueDeclareHandler.getInstance(); - QueueDeleteHandler.getInstance(); - QueuePurgeHandler.getInstance(); - ChannelFlowHandler.getInstance(); - TxSelectHandler.getInstance(); - TxCommitHandler.getInstance(); - TxRollbackHandler.getInstance(); - BasicRejectMethodHandler.getInstance(); - - _state2HandlersMap.put(AMQState.CONNECTION_OPEN, frame2handlerMap); - - frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - - _state2HandlersMap.put(AMQState.CONNECTION_CLOSING, frame2handlerMap); - - } */ - public AMQState getCurrentState() { return _currentState; @@ -217,30 +121,6 @@ public class AMQStateManager implements AMQMethodListener } } -/* - protected <B extends AMQMethodBody> StateAwareMethodListener<B> findStateTransitionHandler(AMQState currentState, - B frame) - // throws IllegalStateTransitionException - { - final Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>> classToHandlerMap = - _state2HandlersMap.get(currentState); - - final StateAwareMethodListener<B> handler = - (classToHandlerMap == null) ? null : (StateAwareMethodListener<B>) classToHandlerMap.get(frame.getClass()); - - if (handler == null) - { - _logger.debug("No state transition handler defined for receiving frame " + frame); - - return null; - } - else - { - return handler; - } - } -*/ - public void addStateListener(StateListener listener) { _logger.debug("Adding state listener"); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java index 3c11bb8a9c..b543728f3b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java @@ -22,7 +22,6 @@ package org.apache.qpid.server.state; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.protocol.AMQMethodEvent; /** * A frame listener that is informed of the protocol state when invoked and has diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java index b732121180..2bd17cfa2f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java @@ -18,12 +18,12 @@ */ package org.apache.qpid.server.stats; -import java.util.Date; -import java.util.concurrent.atomic.AtomicLong; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; + /** * This class collects statistics and counts the total, rate per second and * peak rate per second values for the events that are registered with it. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/AbstractMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/AbstractMessageStore.java index b9adaeacdf..fc5d2a4e42 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/AbstractMessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/AbstractMessageStore.java @@ -20,15 +20,15 @@ */ package org.apache.qpid.server.store; -import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.MessageStoreMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; -import org.apache.qpid.server.logging.LogSubject; +import org.apache.qpid.server.virtualhost.VirtualHost; public abstract class AbstractMessageStore implements MessageStore { - protected LogSubject _logSubject; + private LogSubject _logSubject; public void configure(VirtualHost virtualHost) throws Exception { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java index 09e7fe0a11..fb67500da9 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java @@ -20,12 +20,12 @@ */ package org.apache.qpid.server.store; +import org.apache.qpid.framing.FieldTable; + import java.nio.ByteBuffer; import java.util.Map; import java.util.UUID; -import org.apache.qpid.framing.FieldTable; - public interface ConfigurationRecoveryHandler { QueueRecoveryHandler begin(MessageStore store); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java index 45083c1595..4d63136a9d 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java @@ -20,6 +20,24 @@ */ package org.apache.qpid.server.store; +import org.apache.commons.configuration.Configuration; +import org.apache.log4j.Logger; + +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQStoreException; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +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.logging.LogSubject; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.messages.ConfigStoreMessages; +import org.apache.qpid.server.logging.messages.MessageStoreMessages; +import org.apache.qpid.server.logging.messages.TransactionLogMessages; +import org.apache.qpid.server.message.EnqueableMessage; +import org.apache.qpid.server.queue.AMQQueue; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; @@ -45,23 +63,6 @@ import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import org.apache.commons.configuration.Configuration; -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQStoreException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -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.logging.LogSubject; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.messages.ConfigStoreMessages; -import org.apache.qpid.server.logging.messages.MessageStoreMessages; -import org.apache.qpid.server.logging.messages.TransactionLogMessages; -import org.apache.qpid.server.message.EnqueableMessage; -import org.apache.qpid.server.queue.AMQQueue; - /** * An implementation of a {@link MessageStore} that uses Apache Derby as the persistance * mechanism. @@ -91,7 +92,9 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor private static final String LINKS_TABLE_NAME = "QPID_LINKS"; private static final String BRIDGES_TABLE_NAME = "QPID_BRIDGES"; - + private static final String XID_TABLE_NAME = "QPID_XIDS"; + private static final String XID_ACTIONS_TABLE_NAME = "QPID_XID_ACTIONS"; + private static final int DB_VERSION = 3; @@ -189,6 +192,31 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor + "arguments )" + " values (?, ?, ?, ?, ?, ?)"; + private static final String CREATE_XIDS_TABLE = + "CREATE TABLE "+XID_TABLE_NAME+" ( format bigint not null," + + " global_id varchar(64) for bit data, branch_id varchar(64) for bit data, PRIMARY KEY ( format, " + + "global_id, branch_id ))"; + private static final String INSERT_INTO_XIDS = + "INSERT INTO "+XID_TABLE_NAME+" ( format, global_id, branch_id ) values (?, ?, ?)"; + private static final String DELETE_FROM_XIDS = "DELETE FROM " + XID_TABLE_NAME + + " WHERE format = ? and global_id = ? and branch_id = ?"; + private static final String SELECT_ALL_FROM_XIDS = "SELECT format, global_id, branch_id FROM " + XID_TABLE_NAME; + + + private static final String CREATE_XID_ACTIONS_TABLE = + "CREATE TABLE "+XID_ACTIONS_TABLE_NAME+" ( format bigint not null," + + " global_id varchar(64) for bit data not null, branch_id varchar(64) for bit data not null, " + + "action_type char not null, queue_name varchar(255) not null, message_id bigint not null" + + ", PRIMARY KEY ( " + + "format, global_id, branch_id, action_type, queue_name, message_id))"; + private static final String INSERT_INTO_XID_ACTIONS = + "INSERT INTO "+XID_ACTIONS_TABLE_NAME+" ( format, global_id, branch_id, action_type, " + + "queue_name, message_id ) values (?,?,?,?,?,?) "; + private static final String DELETE_FROM_XID_ACTIONS = "DELETE FROM " + XID_ACTIONS_TABLE_NAME + + " WHERE format = ? and global_id = ? and branch_id = ?"; + private static final String SELECT_ALL_FROM_XID_ACTIONS = + "SELECT action_type, queue_name, message_id FROM " + XID_ACTIONS_TABLE_NAME + + " WHERE format = ? and global_id = ? and branch_id = ?"; private static final String DERBY_SINGLE_DB_SHUTDOWN_CODE = "08006"; @@ -294,7 +322,8 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor _configured = true; } - recoverQueueEntries(recoveryHandler); + TransactionLogRecoveryHandler.DtxRecordRecoveryHandler dtxrh = recoverQueueEntries(recoveryHandler); + recoverXids(dtxrh); } @@ -349,7 +378,8 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor createMessageContentTable(conn); createLinkTable(conn); createBridgeTable(conn); - + createXidTable(conn); + createXidActionTable(conn); conn.close(); } @@ -518,8 +548,38 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor } } + private void createXidTable(final Connection conn) throws SQLException + { + if(!tableExists(XID_TABLE_NAME, conn)) + { + Statement stmt = conn.createStatement(); + try + { + stmt.execute(CREATE_XIDS_TABLE); + } + finally + { + stmt.close(); + } + } + } + private void createXidActionTable(final Connection conn) throws SQLException + { + if(!tableExists(XID_ACTIONS_TABLE_NAME, conn)) + { + Statement stmt = conn.createStatement(); + try + { + stmt.execute(CREATE_XID_ACTIONS_TABLE); + } + finally + { + stmt.close(); + } + } + } private boolean tableExists(final String tableName, final Connection conn) throws SQLException { @@ -650,12 +710,12 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor conn = newAutoCommitConnection(); PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_BRIDGES); - stmt.setLong(1, linkId.getLeastSignificantBits()); - stmt.setLong(2, linkId.getMostSignificantBits()); - try { + stmt.setLong(1, linkId.getLeastSignificantBits()); + stmt.setLong(2, linkId.getMostSignificantBits()); + ResultSet rs = stmt.executeQuery(); try @@ -1110,11 +1170,7 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor insertStmt.setString(3, routingKey == null ? null : routingKey.toString()); if(args != null) { - /* This would be the Java 6 way of setting a Blob - Blob blobArgs = conn.createBlob(); - blobArgs.setBytes(0, args.getDataAsBytes()); - stmt.setBlob(4, blobArgs); - */ + // TODO - In Java 6 we could use create/set Blob byte[] bytes = args.getDataAsBytes(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); insertStmt.setBinaryStream(4, bis, bytes.length); @@ -1712,7 +1768,7 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor if (_logger.isDebugEnabled()) { - _logger.debug("Dequeuing message " + messageId + " on queue " + name );//+ "[Connection" + conn + "]"); + _logger.debug("Dequeuing message " + messageId + " on queue " + name ); } } finally @@ -1729,6 +1785,126 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor } + + private void removeXid(ConnectionWrapper connWrapper, long format, byte[] globalId, byte[] branchId) + throws AMQStoreException + { + Connection conn = connWrapper.getConnection(); + + + try + { + PreparedStatement stmt = conn.prepareStatement(DELETE_FROM_XIDS); + try + { + stmt.setLong(1,format); + stmt.setBytes(2,globalId); + stmt.setBytes(3,branchId); + int results = stmt.executeUpdate(); + + + + if(results != 1) + { + throw new AMQStoreException("Unable to find message with xid"); + } + } + finally + { + stmt.close(); + } + + stmt = conn.prepareStatement(DELETE_FROM_XID_ACTIONS); + try + { + stmt.setLong(1,format); + stmt.setBytes(2,globalId); + stmt.setBytes(3,branchId); + int results = stmt.executeUpdate(); + + } + finally + { + stmt.close(); + } + + } + catch (SQLException e) + { + _logger.error("Failed to dequeue: " + e.getMessage(), e); + throw new AMQStoreException("Error deleting enqueued message with xid", e); + } + + } + + + private void recordXid(ConnectionWrapper connWrapper, long format, byte[] globalId, byte[] branchId, + Transaction.Record[] enqueues, Transaction.Record[] dequeues) throws AMQStoreException + { + Connection conn = connWrapper.getConnection(); + + + try + { + + PreparedStatement stmt = conn.prepareStatement(INSERT_INTO_XIDS); + try + { + stmt.setLong(1,format); + stmt.setBytes(2, globalId); + stmt.setBytes(3, branchId); + stmt.executeUpdate(); + } + finally + { + stmt.close(); + } + + stmt = conn.prepareStatement(INSERT_INTO_XID_ACTIONS); + + try + { + stmt.setLong(1,format); + stmt.setBytes(2, globalId); + stmt.setBytes(3, branchId); + + if(enqueues != null) + { + stmt.setString(4, "E"); + for(Transaction.Record record : enqueues) + { + stmt.setString(5, record.getQueue().getResourceName()); + stmt.setLong(6, record.getMessage().getMessageNumber()); + stmt.executeUpdate(); + } + } + + if(dequeues != null) + { + stmt.setString(4, "D"); + for(Transaction.Record record : dequeues) + { + stmt.setString(5, record.getQueue().getResourceName()); + stmt.setLong(6, record.getMessage().getMessageNumber()); + stmt.executeUpdate(); + } + } + + } + finally + { + stmt.close(); + } + + } + catch (SQLException e) + { + _logger.error("Failed to enqueue: " + e.getMessage(), e); + throw new AMQStoreException("Error writing xid ", e); + } + + } + private static final class ConnectionWrapper { private final Connection _connection; @@ -1922,7 +2098,7 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor - private void recoverQueueEntries(TransactionLogRecoveryHandler recoveryHandler) throws SQLException + private TransactionLogRecoveryHandler.DtxRecordRecoveryHandler recoverQueueEntries(TransactionLogRecoveryHandler recoveryHandler) throws SQLException { Connection conn = newAutoCommitConnection(); try @@ -1953,7 +2129,7 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor stmt.close(); } - queueEntryHandler.completeQueueEntryRecovery(); + return queueEntryHandler.completeQueueEntryRecovery(); } finally { @@ -1961,6 +2137,166 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor } } + private static final class Xid + { + + private final long _format; + private final byte[] _globalId; + private final byte[] _branchId; + + public Xid(long format, byte[] globalId, byte[] branchId) + { + _format = format; + _globalId = globalId; + _branchId = branchId; + } + + public long getFormat() + { + return _format; + } + + public byte[] getGlobalId() + { + return _globalId; + } + + public byte[] getBranchId() + { + return _branchId; + } + } + + private static class RecordImpl implements MessageStore.Transaction.Record, TransactionLogResource, EnqueableMessage + { + + private final String _queueName; + private long _messageNumber; + + public RecordImpl(String queueName, long messageNumber) + { + _queueName = queueName; + _messageNumber = messageNumber; + } + + public TransactionLogResource getQueue() + { + return this; + } + + public EnqueableMessage getMessage() + { + return this; + } + + public long getMessageNumber() + { + return _messageNumber; + } + + public boolean isPersistent() + { + return true; + } + + public StoredMessage getStoredMessage() + { + throw new UnsupportedOperationException(); + } + + public String getResourceName() + { + return _queueName; + } + } + + private void recoverXids(TransactionLogRecoveryHandler.DtxRecordRecoveryHandler dtxrh) throws SQLException + { + Connection conn = newAutoCommitConnection(); + try + { + List<Xid> xids = new ArrayList<Xid>(); + + Statement stmt = conn.createStatement(); + try + { + ResultSet rs = stmt.executeQuery(SELECT_ALL_FROM_XIDS); + try + { + while(rs.next()) + { + + long format = rs.getLong(1); + byte[] globalId = rs.getBytes(2); + byte[] branchId = rs.getBytes(3); + xids.add(new Xid(format, globalId, branchId)); + } + } + finally + { + rs.close(); + } + } + finally + { + stmt.close(); + } + + + + for(Xid xid : xids) + { + List<RecordImpl> enqueues = new ArrayList<RecordImpl>(); + List<RecordImpl> dequeues = new ArrayList<RecordImpl>(); + + PreparedStatement pstmt = conn.prepareStatement(SELECT_ALL_FROM_XID_ACTIONS); + + try + { + pstmt.setLong(1, xid.getFormat()); + pstmt.setBytes(2, xid.getGlobalId()); + pstmt.setBytes(3, xid.getBranchId()); + + ResultSet rs = pstmt.executeQuery(); + try + { + while(rs.next()) + { + + String actionType = rs.getString(1); + String queueName = rs.getString(2); + long messageId = rs.getLong(3); + + RecordImpl record = new RecordImpl(queueName, messageId); + List<RecordImpl> records = "E".equals(actionType) ? enqueues : dequeues; + records.add(record); + } + } + finally + { + rs.close(); + } + } + finally + { + pstmt.close(); + } + + dtxrh.dtxRecord(xid.getFormat(), xid.getGlobalId(), xid.getBranchId(), + enqueues.toArray(new RecordImpl[enqueues.size()]), + dequeues.toArray(new RecordImpl[dequeues.size()])); + } + + + dtxrh.completeDtxRecordRecovery(); + } + finally + { + conn.close(); + } + + } + StorableMessageMetaData getMetaData(long messageId) throws SQLException { @@ -2031,11 +2367,8 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor stmt.setInt(3, offset+chunkData.length); - /* this would be the Java 6 way of doing things - Blob dataAsBlob = conn.createBlob(); - dataAsBlob.setBytes(1L, chunkData); - stmt.setBlob(3, dataAsBlob); - */ + // TODO in Java 6 we could just use blobs + ByteArrayInputStream bis = new ByteArrayInputStream(chunkData); stmt.setBinaryStream(4, bis, chunkData.length); stmt.executeUpdate(); @@ -2181,8 +2514,21 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor { DerbyMessageStore.this.abortTran(_connWrapper); } + + public void removeXid(long format, byte[] globalId, byte[] branchId) throws AMQStoreException + { + DerbyMessageStore.this.removeXid(_connWrapper, format, globalId, branchId); + } + + public void recordXid(long format, byte[] globalId, byte[] branchId, Record[] enqueues, Record[] dequeues) + throws AMQStoreException + { + DerbyMessageStore.this.recordXid(_connWrapper, format, globalId, branchId, enqueues, dequeues); + } } + + private class StoredDerbyMessage implements StoredMessage { @@ -2366,4 +2712,4 @@ public class DerbyMessageStore implements MessageStore, DurableConfigurationStor } } -} +}
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java index 9cd2567b7d..123ecd8145 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.store; import org.apache.commons.configuration.Configuration; + import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java index c5393f73a2..b01e5aa954 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java @@ -20,12 +20,9 @@ */ package org.apache.qpid.server.store; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; - import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.AMQShortString; @@ -38,9 +35,12 @@ import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.ConfigStoreMessages; import org.apache.qpid.server.logging.messages.MessageStoreMessages; import org.apache.qpid.server.message.EnqueableMessage; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.queue.AMQQueue; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + /** A simple message store that stores the messages in a threadsafe structure in memory. */ public class MemoryMessageStore implements MessageStore, DurableConfigurationStore { @@ -78,6 +78,14 @@ public class MemoryMessageStore implements MessageStore, DurableConfigurationSto { } + public void removeXid(long format, byte[] globalId, byte[] branchId) + { + } + + public void recordXid(long format, byte[] globalId, byte[] branchId, Record[] enqueues, Record[] dequeues) + { + } + }; public void configureConfigStore(String name, ConfigurationRecoveryHandler handler, Configuration configuration, LogSubject logSubject) throws Exception diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java index 88c95ad65e..00bb0449d6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStore.java @@ -20,9 +20,9 @@ */ package org.apache.qpid.server.store; +import org.apache.commons.configuration.Configuration; import org.apache.qpid.AMQStoreException; import org.apache.qpid.server.logging.LogSubject; -import org.apache.commons.configuration.Configuration; import org.apache.qpid.server.message.EnqueableMessage; /** @@ -125,7 +125,16 @@ public interface MessageStore void abortTran() throws AMQStoreException; + public static interface Record + { + TransactionLogResource getQueue(); + EnqueableMessage getMessage(); + } + + void removeXid(long format, byte[] globalId, byte[] branchId) throws AMQStoreException; + void recordXid(long format, byte[] globalId, byte[] branchId, Record[] enqueues, Record[] dequeues) + throws AMQStoreException; } public void configureTransactionLog(String name, diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreClosedException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreClosedException.java index 3d1538c7eb..b0a736c66c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreClosedException.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreClosedException.java @@ -1,6 +1,4 @@ -package org.apache.qpid.server.store; - -import org.apache.qpid.AMQException;/* +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,6 +19,10 @@ import org.apache.qpid.AMQException;/* * */ +package org.apache.qpid.server.store; + +import org.apache.qpid.AMQException; + /** * NOTE: this class currently extends AMQException but * we should be using AMQExceptions internally in the code base for Protocol errors hence diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java index 802596ed1e..48ca72718b 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/TransactionLogRecoveryHandler.java @@ -28,6 +28,13 @@ public interface TransactionLogRecoveryHandler { void queueEntry(String queuename, long messageId); - void completeQueueEntryRecovery(); + DtxRecordRecoveryHandler completeQueueEntryRecovery(); + } + + public static interface DtxRecordRecoveryHandler + { + void dtxRecord(long format, byte[] globalId, byte[] branchId, MessageStore.Transaction.Record[] enqueues, MessageStore.Transaction.Record[] dequeues); + + void completeDtxRecordRecovery(); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java index f511cc0dc9..6b2dff7165 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/AssignedSubscriptionMessageGroupManager.java @@ -20,11 +20,12 @@ */ package org.apache.qpid.server.subscription; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.QueueEntry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.QueueEntry; + import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; @@ -47,7 +48,10 @@ public class AssignedSubscriptionMessageGroupManager implements MessageGroupMana private static int pow2(final int i) { int val = 1; - while(val < i) val<<=1; + while(val < i) + { + val<<=1; + } return val; } @@ -111,11 +115,15 @@ public class AssignedSubscriptionMessageGroupManager implements MessageGroupMana public boolean visit(final QueueEntry entry) { if(!entry.isAvailable()) + { return false; + } Object groupId = entry.getMessage().getMessageHeader().getHeader(_groupId); if(groupId == null) + { return false; + } Integer group = groupId.hashCode() & _groupMask; Subscription assignedSub = _groupMap.get(group); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ClientDeliveryMethod.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ClientDeliveryMethod.java index fbc8b3af7d..632b59d3fa 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ClientDeliveryMethod.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ClientDeliveryMethod.java @@ -20,8 +20,8 @@ */ package org.apache.qpid.server.subscription; -import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.AMQException; +import org.apache.qpid.server.queue.QueueEntry; public interface ClientDeliveryMethod { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java index 689e48b4cf..62e94f6f2e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/DefinedGroupMessageGroupManager.java @@ -20,12 +20,13 @@ */ package org.apache.qpid.server.subscription; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueEntry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; @@ -188,7 +189,9 @@ public class DefinedGroupMessageGroupManager implements MessageGroupManager public boolean visit(final QueueEntry entry) { if(!entry.isAvailable()) + { return false; + } Object groupId = getKey(entry); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java index 80c5e2866c..cf2754862d 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ExplicitAcceptDispositionChangeListener.java @@ -20,10 +20,11 @@ */ package org.apache.qpid.server.subscription; -import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.queue.QueueEntry; import org.apache.log4j.Logger; +import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.transport.ServerSession; + class ExplicitAcceptDispositionChangeListener implements ServerSession.MessageDispositionChangeListener { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java index a61b0b4e82..1e37675c98 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/ImplicitAcceptDispositionChangeListener.java @@ -20,10 +20,11 @@ */ package org.apache.qpid.server.subscription; -import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.queue.QueueEntry; import org.apache.log4j.Logger; +import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.transport.ServerSession; + class ImplicitAcceptDispositionChangeListener implements ServerSession.MessageDispositionChangeListener { private static final Logger _logger = Logger.getLogger(ImplicitAcceptDispositionChangeListener.class); @@ -71,8 +72,6 @@ class ImplicitAcceptDispositionChangeListener implements ServerSession.MessageDi public boolean acquire() { boolean acquired = _entry.acquire(getSubscription()); - //TODO - why acknowledge here??? seems bizarre... - // getSubscription().getSession().acknowledge(getSubscription(), _entry); return acquired; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java index bc1be90531..66825caa24 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java @@ -22,7 +22,6 @@ package org.apache.qpid.server.subscription; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.QueueEntry; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactory.java index 0fd7fdffe5..3659243cea 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactory.java @@ -20,22 +20,21 @@ */ package org.apache.qpid.server.subscription; -import java.util.Map; - import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.flow.FlowCreditManager; import org.apache.qpid.server.flow.FlowCreditManager_0_10; -import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.AMQChannel; import org.apache.qpid.transport.MessageAcceptMode; import org.apache.qpid.transport.MessageAcquireMode; import org.apache.qpid.transport.MessageFlowMode; +import java.util.Map; + /** * Allows the customisation of the creation of a subscription. This is typically done within an AMQQueue. This factory * primarily assists testing although in future more sophisticated subscribers may need a different subscription diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java index 1622d63648..a2e30b6ae7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java @@ -20,9 +20,6 @@ */ package org.apache.qpid.server.subscription; -import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; - import org.apache.qpid.AMQException; import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.framing.AMQShortString; @@ -38,6 +35,9 @@ import org.apache.qpid.transport.MessageAcceptMode; import org.apache.qpid.transport.MessageAcquireMode; import org.apache.qpid.transport.MessageFlowMode; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + public class SubscriptionFactoryImpl implements SubscriptionFactory { private static final AtomicLong SUB_ID_GENERATOR = new AtomicLong(0); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java index 23ae14eef1..1f25c215cc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java @@ -24,7 +24,6 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.common.AMQPFilterTypes; -import org.apache.qpid.common.ClientProperties; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.AMQChannel; @@ -320,9 +319,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage private final Boolean _autoClose; - - private static final String CLIENT_PROPERTIES_INSTANCE = ClientProperties.instance.toString(); - private AMQQueue _queue; private final AtomicBoolean _deleted = new AtomicBoolean(false); @@ -479,10 +475,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage public boolean hasInterest(QueueEntry entry) { - - - - //check that the message hasn't been rejected if (entry.isRejectedBy(getSubscriptionID())) { @@ -490,27 +482,21 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage { _logger.debug("Subscription:" + this + " rejected message:" + entry); } -// return false; } if (_noLocal) { - AMQMessage message = (AMQMessage) entry.getMessage(); - //todo - client id should be recorded so we don't have to handle - // the case where this is null. - final Object publisher = message.getPublisherIdentifier(); + final Object publisherReference = message.getConnectionIdentifier(); // We don't want local messages so check to see if message is one we sent - Object localInstance = getProtocolSession(); + Object localReference = getProtocolSession().getReference(); - if(publisher.equals(localInstance)) + if(publisherReference != null && publisherReference.equals(localReference)) { return false; } - - } @@ -585,7 +571,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage public boolean wouldSuspend(QueueEntry msg) { - return !_creditManager.useCreditForMessage(msg.getMessage().getSize());//_channel.wouldSuspend(msg.getMessage()); + return !_creditManager.useCreditForMessage(msg.getMessage().getSize()); } public boolean trySendLock() diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java index 3e6299cb8a..bf5ce31bd9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java @@ -20,11 +20,9 @@ */ package org.apache.qpid.server.subscription; -import org.apache.qpid.server.subscription.Subscription; - -import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; public class SubscriptionList { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java index bde756dd03..76d975a789 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java @@ -20,46 +20,58 @@ */ package org.apache.qpid.server.subscription; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SUBSCRIPTION_FORMAT; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.QUEUE_FORMAT; - -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.queue.InboundMessageAdapter; -import org.apache.qpid.server.queue.QueueEntry; +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.flow.FlowCreditManager; +import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.flow.CreditCreditManager; -import org.apache.qpid.server.flow.WindowCreditManager; +import org.apache.qpid.server.flow.FlowCreditManager; import org.apache.qpid.server.flow.FlowCreditManager_0_10; -import org.apache.qpid.server.filter.FilterManager; +import org.apache.qpid.server.flow.WindowCreditManager; +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.GenericActor; import org.apache.qpid.server.logging.messages.ChannelMessages; import org.apache.qpid.server.logging.messages.SubscriptionMessages; -import org.apache.qpid.server.logging.LogActor; -import org.apache.qpid.server.logging.LogSubject; +import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.message.AMQMessage; +import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.BaseQueue; +import org.apache.qpid.server.queue.InboundMessageAdapter; +import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.txn.AutoCommitTransaction; -import org.apache.qpid.transport.*; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.AMQException; -import org.apache.qpid.transport.util.Logger; +import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.transport.DeliveryProperties; +import org.apache.qpid.transport.Header; +import org.apache.qpid.transport.MessageAcceptMode; +import org.apache.qpid.transport.MessageAcquireMode; +import org.apache.qpid.transport.MessageCreditUnit; +import org.apache.qpid.transport.MessageDeliveryPriority; +import org.apache.qpid.transport.MessageFlowMode; +import org.apache.qpid.transport.MessageProperties; +import org.apache.qpid.transport.MessageTransfer; +import org.apache.qpid.transport.Method; +import org.apache.qpid.transport.Option; +import org.apache.qpid.transport.ReplyTo; +import org.apache.qpid.transport.Struct; import org.apache.qpid.url.AMQBindingURL; +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.QUEUE_FORMAT; +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SUBSCRIPTION_FORMAT; + import java.net.URISyntaxException; +import java.nio.ByteBuffer; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; @@ -67,13 +79,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.ConcurrentHashMap; -import java.nio.ByteBuffer; +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 { @@ -387,6 +398,10 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr { deliveryProps.setTimestamp(origDeliveryProps.getTimestamp()); } + if(origDeliveryProps.hasTtl()) + { + deliveryProps.setTtl(origDeliveryProps.getTtl()); + } } @@ -537,36 +552,8 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr messageProps.setCorrelationId(serverMsg.getMessageHeader().getCorrelationId().getBytes()); } - // TODO - ReplyTo - - final Map<String, Object> appHeaders = new HashMap<String, Object>(); - - /*properties.getHeaders().processOverElements( - new FieldTable.FieldTableElementProcessor() - { - - public boolean processElement(String propertyName, AMQTypedValue value) - { - Object val = value.getValue(); - if(val instanceof AMQShortString) - { - val = val.toString(); - } - appHeaders.put(propertyName, val); - return true; - } - - public Object getResult() - { - return appHeaders; - } - }); - - - messageProps.setApplicationHeaders(appHeaders); -*/ Header header = new Header(deliveryProps, messageProps, null); xfr = batch ? new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body, BATCHED) : new MessageTransfer(_destination,_acceptMode,_acquireMode,header, body); @@ -690,7 +677,10 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr { entry.setRedelivered(); entry.routeToAlternate(); - + if(entry.isAcquiredBy(this)) + { + entry.discard(); + } } void release(final QueueEntry entry, final boolean setRedelivered) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java index abbc5a3805..637ea7dffc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java @@ -24,8 +24,8 @@ import org.apache.qpid.transport.network.NetworkTransport; public class QpidAcceptor { - NetworkTransport _transport; - String _protocol; + private NetworkTransport _transport; + private String _protocol; public QpidAcceptor(NetworkTransport transport, String protocol) { _transport = transport; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java index 04cdbf2b25..c38f3d0761 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java @@ -20,27 +20,6 @@ */ package org.apache.qpid.server.transport; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT; -import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORMAT; - -import java.util.concurrent.atomic.AtomicLong; - -import javax.management.JMException; - -import org.apache.qpid.server.management.ManagedObject; - -import org.apache.qpid.server.management.Managable; - -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 javax.security.auth.Subject; - import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.configuration.ConnectionConfig; @@ -49,6 +28,8 @@ import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.GenericActor; import org.apache.qpid.server.logging.messages.ConnectionMessages; +import org.apache.qpid.server.management.Managable; +import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.security.AuthorizationHolder; @@ -62,8 +43,20 @@ 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.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT; +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT; +import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORMAT; + +import javax.management.JMException; +import javax.security.auth.Subject; +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; public class ServerConnection extends Connection implements Managable, AMQConnectionModel, LogSubject, AuthorizationHolder { @@ -114,7 +107,7 @@ public class ServerConnection extends Connection implements Managable, AMQConnec { _onOpenTask.run(); } - _actor.message(ConnectionMessages.OPEN(getClientId(), "0-10", true, true)); + _actor.message(ConnectionMessages.OPEN(getClientId(), "0-10", getClientVersion(), true, true, true)); getVirtualHost().getConnectionRegistry().registerConnection(this); } @@ -495,4 +488,14 @@ public class ServerConnection extends Connection implements Managable, AMQConnec _mBean = null; } } + + public String getClientId() + { + return getConnectionDelegate().getClientId(); + } + + public String getClientVersion() + { + return getConnectionDelegate().getClientVersion(); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java index 66ed6f1e62..28d8cb2ec7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java @@ -20,17 +20,10 @@ */ package org.apache.qpid.server.transport; -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 java.util.StringTokenizer; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; +import static org.apache.qpid.transport.Connection.State.CLOSE_RCVD; + 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.protocol.AMQConnectionModel; @@ -41,24 +34,25 @@ import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.subscription.Subscription_0_10; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.Binary; -import org.apache.qpid.transport.Connection; -import org.apache.qpid.transport.ConnectionClose; -import org.apache.qpid.transport.ConnectionCloseCode; -import org.apache.qpid.transport.ConnectionOpen; -import org.apache.qpid.transport.ConnectionOpenOk; -import org.apache.qpid.transport.ConnectionStartOk; -import org.apache.qpid.transport.ConnectionTuneOk; -import org.apache.qpid.transport.ServerDelegate; -import org.apache.qpid.transport.Session; -import org.apache.qpid.transport.SessionAttach; -import org.apache.qpid.transport.SessionDelegate; -import org.apache.qpid.transport.SessionDetach; -import org.apache.qpid.transport.SessionDetachCode; -import org.apache.qpid.transport.SessionDetached; +import org.apache.qpid.transport.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; +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 java.util.StringTokenizer; public class ServerConnectionDelegate extends ServerDelegate { + private static final Logger LOGGER = LoggerFactory.getLogger(ServerConnectionDelegate.class); + private final String _localFQDN; private final IApplicationRegistry _appRegistry; private int _maxNoOfChannels; @@ -140,17 +134,20 @@ public class ServerConnectionDelegate extends ServerDelegate } } + @Override public void connectionClose(Connection conn, ConnectionClose close) { + final ServerConnection sconn = (ServerConnection) conn; try { - ((ServerConnection) conn).logClosed(); + sconn.logClosed(); } finally { - super.connectionClose(conn, close); + sconn.closeCode(close); + sconn.setState(CLOSE_RCVD); + sendConnectionCloseOkAndCloseSender(conn); } - } public void connectionOpen(Connection conn, ConnectionOpen open) @@ -177,19 +174,19 @@ public class ServerConnectionDelegate extends ServerDelegate if (!vhost.getSecurityManager().accessVirtualhost(vhostName, ((ProtocolEngine) sconn.getConfig()).getRemoteAddress())) { - sconn.invoke(new ConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, "Permission denied '"+vhostName+"'")); sconn.setState(Connection.State.CLOSING); + sconn.invoke(new ConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, "Permission denied '"+vhostName+"'")); } else { - sconn.invoke(new ConnectionOpenOk(Collections.emptyList())); - sconn.setState(Connection.State.OPEN); + sconn.setState(Connection.State.OPEN); + sconn.invoke(new ConnectionOpenOk(Collections.emptyList())); } } else { - sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '"+vhostName+"'")); sconn.setState(Connection.State.CLOSING); + sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '"+vhostName+"'")); } } @@ -202,9 +199,9 @@ public class ServerConnectionDelegate extends ServerDelegate if (okChannelMax > getChannelMax()) { - _logger.error("Connection '" + sconn.getConnectionId() + "' being severed, " + + LOGGER.error("Connection '" + sconn.getConnectionId() + "' being severed, " + "client connectionTuneOk returned a channelMax (" + okChannelMax + - ") above the servers offered limit (" + getChannelMax() +")"); + ") above the server's offered limit (" + getChannelMax() +")"); //Due to the error we must forcefully close the connection without negotiation sconn.getSender().close(); @@ -234,23 +231,26 @@ public class ServerConnectionDelegate extends ServerDelegate @Override public void sessionDetach(Connection conn, SessionDetach dtc) { - // To ensure a clean detach, we unregister any remaining subscriptions. Unregister ensures - // that any in-progress delivery (SubFlushRunner/QueueRunner) is completed before the unregister + // To ensure a clean detach, we stop any remaining subscriptions. Stop ensures + // that any in-progress delivery (SubFlushRunner/QueueRunner) is completed before the stop // completes. - unregisterAllSubscriptions(conn, dtc); + stopAllSubscriptions(conn, dtc); + Session ssn = conn.getSession(dtc.getChannel()); + ((ServerSession)ssn).setClose(true); super.sessionDetach(conn, dtc); } - private void unregisterAllSubscriptions(Connection conn, SessionDetach dtc) + private void stopAllSubscriptions(Connection conn, SessionDetach dtc) { final ServerSession ssn = (ServerSession) conn.getSession(dtc.getChannel()); final Collection<Subscription_0_10> subs = ssn.getSubscriptions(); for (Subscription_0_10 subscription_0_10 : subs) { - ssn.unregister(subscription_0_10); + subscription_0_10.stop(); } } + @Override public void sessionAttach(final Connection conn, final SessionAttach atc) { @@ -258,8 +258,7 @@ public class ServerConnectionDelegate extends ServerDelegate if(isSessionNameUnique(atc.getName(), conn)) { - ssn = sessionAttachImpl(conn, atc); - conn.registerSession(ssn); + super.sessionAttach(conn, atc); ((ServerConnection)conn).checkForNotification(); } else @@ -299,4 +298,14 @@ public class ServerConnectionDelegate extends ServerDelegate { return _clientProperties; } + + public String getClientId() + { + return _clientProperties == null ? null : (String) _clientProperties.get(ConnectionStartProperties.CLIENT_ID_0_10); + } + + public String getClientVersion() + { + return _clientProperties == null ? null : (String) _clientProperties.get(ConnectionStartProperties.VERSION_0_10); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java index 17c7bed601..bb545164fb 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionMBean.java @@ -20,17 +20,6 @@ */ package org.apache.qpid.server.transport; -import java.io.IOException; -import java.util.Date; -import java.util.List; -import javax.management.JMException; -import javax.management.NotCompliantMBeanException; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; - -import org.apache.qpid.common.ClientProperties; import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor; import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; import org.apache.qpid.server.logging.actors.CurrentActor; @@ -39,6 +28,16 @@ import org.apache.qpid.server.management.AbstractAMQManagedConnectionObject; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.protocol.AMQSessionModel; +import javax.management.JMException; +import javax.management.NotCompliantMBeanException; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import java.io.IOException; +import java.util.Date; +import java.util.List; + /** * This MBean class implements the management interface. In order to make more attributes, operations and notifications * available over JMX simply augment the ManagedConnection interface and add the appropriate implementation here. @@ -76,7 +75,7 @@ public class ServerConnectionMBean extends AbstractAMQManagedConnectionObject @Override public String getVersion() { - return String.valueOf(_serverConnection.getConnectionDelegate().getClientProperties().get(ClientProperties.version.toString())); + return String.valueOf(_serverConnection.getClientVersion()); } @Override @@ -132,7 +131,7 @@ public class ServerConnectionMBean extends AbstractAMQManagedConnectionObject } else if (session.isTransactional()) { - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { session.commit(); @@ -154,7 +153,7 @@ public class ServerConnectionMBean extends AbstractAMQManagedConnectionObject } else if (session.isTransactional()) { - CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger())); + CurrentActor.set(new ManagementActor(getLogActor().getRootMessageLogger())); try { session.rollback(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java index 62a1e2b0f5..d63934e6be 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java @@ -21,6 +21,11 @@ package org.apache.qpid.server.transport; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT; +import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.message.MessageMetaData_0_10; +import org.apache.qpid.server.message.MessageTransferMessage; +import org.apache.qpid.server.txn.RollbackOnlyDtxException; +import org.apache.qpid.server.txn.TimeoutDtxException; import static org.apache.qpid.util.Serial.gt; import java.security.Principal; @@ -30,17 +35,21 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; + 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.configuration.ConfigStore; @@ -64,24 +73,19 @@ import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.subscription.Subscription_0_10; +import org.apache.qpid.server.txn.AlreadyKnownDtxException; import org.apache.qpid.server.txn.AsyncAutoCommitTransaction; +import org.apache.qpid.server.txn.DistributedTransaction; +import org.apache.qpid.server.txn.DtxNotSelectedException; +import org.apache.qpid.server.txn.IncorrectDtxStateException; +import org.apache.qpid.server.txn.JoinAndResumeDtxException; import org.apache.qpid.server.txn.LocalTransaction; +import org.apache.qpid.server.txn.NotAssociatedDtxException; import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.txn.SuspendAndFailDtxException; +import org.apache.qpid.server.txn.UnknownDtxBranchException; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.Binary; -import org.apache.qpid.transport.Connection; -import org.apache.qpid.transport.MessageCreditUnit; -import org.apache.qpid.transport.MessageFlow; -import org.apache.qpid.transport.MessageFlowMode; -import org.apache.qpid.transport.MessageSetFlowMode; -import org.apache.qpid.transport.MessageStop; -import org.apache.qpid.transport.MessageTransfer; -import org.apache.qpid.transport.Method; -import org.apache.qpid.transport.Range; -import org.apache.qpid.transport.RangeSet; -import org.apache.qpid.transport.RangeSetFactory; -import org.apache.qpid.transport.Session; -import org.apache.qpid.transport.SessionDelegate; +import org.apache.qpid.transport.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,13 +104,12 @@ public class ServerSession extends Session private long _createTime = System.currentTimeMillis(); private LogActor _actor = GenericActor.getInstance(this); - private final ConcurrentMap<AMQQueue, Boolean> _blockingQueues = new ConcurrentHashMap<AMQQueue, Boolean>(); + private final Set<AMQQueue> _blockingQueues = new ConcurrentSkipListSet<AMQQueue>(); private final AtomicBoolean _blocking = new AtomicBoolean(false); private ChannelLogSubject _logSubject; private final AtomicInteger _outstandingCredit = new AtomicInteger(UNLIMITED_CREDIT); - public static interface MessageDispositionChangeListener { public void onAccept(); @@ -356,7 +359,15 @@ public class ServerSession extends Session public void onClose() { - _transaction.rollback(); + if(_transaction instanceof LocalTransaction) + { + _transaction.rollback(); + } + else if(_transaction instanceof DistributedTransaction) + { + getVirtualHost().getDtxRegistry().endAssociations(this); + } + for(MessageDispositionChangeListener listener : _messageDispositionListenerMap.values()) { listener.onRelease(true); @@ -392,6 +403,9 @@ public class ServerSession extends Session public void onRollback() { + // The client has acknowledge the message and therefore have seen it. + // In the event of rollback, the message must be marked as redelivered. + entry.setRedelivered(); entry.release(); } }); @@ -452,6 +466,95 @@ public class ServerSession extends Session _txnStarts.incrementAndGet(); } + public void selectDtx() + { + _transaction = new DistributedTransaction(this, getMessageStore(), getVirtualHost()); + + } + + + public void startDtx(Xid xid, boolean join, boolean resume) + throws JoinAndResumeDtxException, + UnknownDtxBranchException, + AlreadyKnownDtxException, + DtxNotSelectedException + { + DistributedTransaction distributedTransaction = assertDtxTransaction(); + distributedTransaction.start(xid, join, resume); + } + + + public void endDtx(Xid xid, boolean fail, boolean suspend) + throws NotAssociatedDtxException, + UnknownDtxBranchException, + DtxNotSelectedException, + SuspendAndFailDtxException, TimeoutDtxException + { + DistributedTransaction distributedTransaction = assertDtxTransaction(); + distributedTransaction.end(xid, fail, suspend); + } + + + public long getTimeoutDtx(Xid xid) + throws UnknownDtxBranchException + { + return getVirtualHost().getDtxRegistry().getTimeout(xid); + } + + + public void setTimeoutDtx(Xid xid, long timeout) + throws UnknownDtxBranchException + { + getVirtualHost().getDtxRegistry().setTimeout(xid, timeout); + } + + + public void prepareDtx(Xid xid) + throws UnknownDtxBranchException, + IncorrectDtxStateException, AMQStoreException, RollbackOnlyDtxException, TimeoutDtxException + { + getVirtualHost().getDtxRegistry().prepare(xid); + } + + public void commitDtx(Xid xid, boolean onePhase) + throws UnknownDtxBranchException, + IncorrectDtxStateException, AMQStoreException, RollbackOnlyDtxException, TimeoutDtxException + { + getVirtualHost().getDtxRegistry().commit(xid, onePhase); + } + + + public void rollbackDtx(Xid xid) + throws UnknownDtxBranchException, + IncorrectDtxStateException, AMQStoreException, TimeoutDtxException + { + getVirtualHost().getDtxRegistry().rollback(xid); + } + + + public void forgetDtx(Xid xid) throws UnknownDtxBranchException, IncorrectDtxStateException + { + getVirtualHost().getDtxRegistry().forget(xid); + } + + public List<Xid> recoverDtx() + { + return getVirtualHost().getDtxRegistry().recover(); + } + + private DistributedTransaction assertDtxTransaction() throws DtxNotSelectedException + { + if(_transaction instanceof DistributedTransaction) + { + return (DistributedTransaction) _transaction; + } + else + { + throw new DtxNotSelectedException(); + } + } + + public void commit() { _transaction.commit(); @@ -524,12 +627,12 @@ public class ServerSession extends Session public Principal getAuthorizedPrincipal() { - return ((ServerConnection) getConnection()).getAuthorizedPrincipal(); + return getConnection().getAuthorizedPrincipal(); } public Subject getAuthorizedSubject() { - return ((ServerConnection) getConnection()).getAuthorizedSubject(); + return getConnection().getAuthorizedSubject(); } public void addSessionCloseTask(Task task) @@ -544,7 +647,7 @@ public class ServerSession extends Session public Object getReference() { - return ((ServerConnection) getConnection()).getReference(); + return getConnection().getReference(); } public MessageStore getMessageStore() @@ -624,7 +727,7 @@ public class ServerSession extends Session public AMQConnectionModel getConnectionModel() { - return (ServerConnection) getConnection(); + return getConnection(); } public String getClientID() @@ -632,6 +735,12 @@ public class ServerSession extends Session return getConnection().getClientId(); } + @Override + public ServerConnection getConnection() + { + return (ServerConnection) super.getConnection(); + } + public LogActor getLogActor() { return _actor; @@ -676,7 +785,8 @@ public class ServerSession extends Session public void block(AMQQueue queue) { - if(_blockingQueues.putIfAbsent(queue, Boolean.TRUE) == null) + + if(_blockingQueues.add(queue)) { if(_blocking.compareAndSet(false,true)) @@ -694,7 +804,7 @@ public class ServerSession extends Session { if(_blockingQueues.remove(queue) && _blockingQueues.isEmpty()) { - if(_blocking.compareAndSet(true,false)) + if(_blocking.compareAndSet(true,false) && !isClosing()) { _actor.message(_logSubject, ChannelMessages.FLOW_REMOVED()); @@ -710,11 +820,19 @@ public class ServerSession extends Session } } + public boolean onSameConnection(InboundMessage inbound) + { + return ((inbound instanceof MessageTransferMessage) + && ((MessageTransferMessage)inbound).getConnectionReference() == getConnection().getReference()) + || ((inbound instanceof MessageMetaData_0_10) + && (((MessageMetaData_0_10)inbound).getConnectionReference())== getConnection().getReference()); + } + public String toLogString() { - long connectionId = getConnection() instanceof ServerConnection - ? ((ServerConnection) getConnection()).getConnectionId() + long connectionId = super.getConnection() instanceof ServerConnection + ? getConnection().getConnectionId() : -1; String remoteAddress = _connectionConfig instanceof ProtocolEngine @@ -749,6 +867,16 @@ public class ServerSession extends Session } } + void stopSubscriptions() + { + final Collection<Subscription_0_10> subscriptions = getSubscriptions(); + for (Subscription_0_10 subscription_0_10 : subscriptions) + { + subscription_0_10.stop(); + } + } + + public void receivedComplete() { final Collection<Subscription_0_10> subscriptions = getSubscriptions(); @@ -889,4 +1017,14 @@ public class ServerSession extends Session return _future.isComplete(); } } + + protected void setClose(boolean close) + { + super.setClose(close); + } + + public int compareTo(AMQSessionModel session) + { + return getId().toString().compareTo(session.getID().toString()); + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java index 2eab65cf8a..c94a476712 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java @@ -20,13 +20,10 @@ */ package org.apache.qpid.server.transport; -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; +import org.apache.qpid.AMQStoreException; import org.apache.qpid.AMQUnknownExchangeType; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; @@ -54,10 +51,24 @@ 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.txn.AlreadyKnownDtxException; +import org.apache.qpid.server.txn.DtxNotSelectedException; +import org.apache.qpid.server.txn.IncorrectDtxStateException; +import org.apache.qpid.server.txn.JoinAndResumeDtxException; +import org.apache.qpid.server.txn.NotAssociatedDtxException; +import org.apache.qpid.server.txn.RollbackOnlyDtxException; import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.txn.SuspendAndFailDtxException; +import org.apache.qpid.server.txn.TimeoutDtxException; +import org.apache.qpid.server.txn.UnknownDtxBranchException; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.*; +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.List; +import java.util.Map; + public class ServerSessionDelegate extends SessionDelegate { private static final Logger LOGGER = Logger.getLogger(ServerSessionDelegate.class); @@ -154,7 +165,12 @@ public class ServerSessionDelegate extends SessionDelegate @Override public void messageSubscribe(Session session, MessageSubscribe method) { - //TODO - work around broken Python tests + /* + TODO - work around broken Python tests + Correct code should read like + if not hasAcceptMode() exception ILLEGAL_ARGUMENT "Accept-mode not supplied" + else if not method.hasAcquireMode() exception ExecutionErrorCode.ILLEGAL_ARGUMENT, "Acquire-mode not supplied" + */ if(!method.hasAcceptMode()) { method.setAcceptMode(MessageAcceptMode.EXPLICIT); @@ -165,15 +181,7 @@ public class ServerSessionDelegate extends SessionDelegate } - /* if(!method.hasAcceptMode()) - { - exception(session,method,ExecutionErrorCode.ILLEGAL_ARGUMENT, "Accept-mode not supplied"); - } - else if(!method.hasAcquireMode()) - { - exception(session,method,ExecutionErrorCode.ILLEGAL_ARGUMENT, "Acquire-mode not supplied"); - } - else */if(!method.hasQueue()) + if(!method.hasQueue()) { exception(session,method,ExecutionErrorCode.ILLEGAL_ARGUMENT, "queue not supplied"); } @@ -201,6 +209,10 @@ public class ServerSessionDelegate extends SessionDelegate { exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session"); } + else if(queue.isExclusive() && queue.getExclusiveOwningSession() != null && queue.getExclusiveOwningSession() != session) + { + exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session"); + } else { if(queue.isExclusive()) @@ -223,7 +235,6 @@ public class ServerSessionDelegate extends SessionDelegate } }); } - } FlowCreditManager_0_10 creditManager = new WindowCreditManager(0L,0L); @@ -283,6 +294,7 @@ public class ServerSessionDelegate extends SessionDelegate } final MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr); + messageMetaData.setConnectionReference(((ServerSession)ssn).getReference()); if (!getVirtualHost(ssn).getSecurityManager().authorisePublish(messageMetaData.isImmediate(), messageMetaData.getRoutingKey(), exchange.getName())) { @@ -428,6 +440,235 @@ public class ServerSessionDelegate extends SessionDelegate ((ServerSession)session).rollback(); } + @Override + public void dtxSelect(Session session, DtxSelect method) + { + // TODO - check current tx mode + ((ServerSession)session).selectDtx(); + } + + @Override + public void dtxStart(Session session, DtxStart method) + { + XaResult result = new XaResult(); + result.setStatus(DtxXaStatus.XA_OK); + try + { + ((ServerSession)session).startDtx(method.getXid(), method.getJoin(), method.getResume()); + session.executionResult(method.getId(), result); + } + catch(JoinAndResumeDtxException e) + { + exception(session, method, ExecutionErrorCode.COMMAND_INVALID, e.getMessage()); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Unknown xid " + method.getXid()); + } + catch(AlreadyKnownDtxException e) + { + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Xid already started an neither join nor " + + "resume set" + method.getXid()); + } + catch(DtxNotSelectedException e) + { + exception(session, method, ExecutionErrorCode.COMMAND_INVALID, e.getMessage()); + } + + } + + @Override + public void dtxEnd(Session session, DtxEnd method) + { + XaResult result = new XaResult(); + result.setStatus(DtxXaStatus.XA_OK); + try + { + try + { + ((ServerSession)session).endDtx(method.getXid(), method.getFail(), method.getSuspend()); + } + catch (TimeoutDtxException e) + { + result.setStatus(DtxXaStatus.XA_RBTIMEOUT); + } + session.executionResult(method.getId(), result); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + catch(NotAssociatedDtxException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + catch(DtxNotSelectedException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + catch(SuspendAndFailDtxException e) + { + exception(session, method, ExecutionErrorCode.COMMAND_INVALID, e.getMessage()); + } + + } + + @Override + public void dtxCommit(Session session, DtxCommit method) + { + XaResult result = new XaResult(); + result.setStatus(DtxXaStatus.XA_OK); + try + { + try + { + ((ServerSession)session).commitDtx(method.getXid(), method.getOnePhase()); + } + catch (RollbackOnlyDtxException e) + { + result.setStatus(DtxXaStatus.XA_RBROLLBACK); + } + catch (TimeoutDtxException e) + { + result.setStatus(DtxXaStatus.XA_RBTIMEOUT); + } + session.executionResult(method.getId(), result); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, e.getMessage()); + } + catch(IncorrectDtxStateException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + catch(AMQStoreException e) + { + exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public void dtxForget(Session session, DtxForget method) + { + try + { + ((ServerSession)session).forgetDtx(method.getXid()); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, e.getMessage()); + } + catch(IncorrectDtxStateException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + + } + + @Override + public void dtxGetTimeout(Session session, DtxGetTimeout method) + { + GetTimeoutResult result = new GetTimeoutResult(); + try + { + result.setTimeout(((ServerSession) session).getTimeoutDtx(method.getXid())); + session.executionResult(method.getId(), result); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, e.getMessage()); + } + } + + @Override + public void dtxPrepare(Session session, DtxPrepare method) + { + XaResult result = new XaResult(); + result.setStatus(DtxXaStatus.XA_OK); + try + { + try + { + ((ServerSession)session).prepareDtx(method.getXid()); + } + catch (RollbackOnlyDtxException e) + { + result.setStatus(DtxXaStatus.XA_RBROLLBACK); + } + catch (TimeoutDtxException e) + { + result.setStatus(DtxXaStatus.XA_RBTIMEOUT); + } + session.executionResult((int) method.getId(), result); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, e.getMessage()); + } + catch(IncorrectDtxStateException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + catch(AMQStoreException e) + { + exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public void dtxRecover(Session session, DtxRecover method) + { + RecoverResult result = new RecoverResult(); + List inDoubt = ((ServerSession)session).recoverDtx(); + result.setInDoubt(inDoubt); + session.executionResult(method.getId(), result); + } + + @Override + public void dtxRollback(Session session, DtxRollback method) + { + + XaResult result = new XaResult(); + result.setStatus(DtxXaStatus.XA_OK); + try + { + try + { + ((ServerSession)session).rollbackDtx(method.getXid()); + } + catch (TimeoutDtxException e) + { + result.setStatus(DtxXaStatus.XA_RBTIMEOUT); + } + session.executionResult(method.getId(), result); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, e.getMessage()); + } + catch(IncorrectDtxStateException e) + { + exception(session, method, ExecutionErrorCode.ILLEGAL_STATE, e.getMessage()); + } + catch(AMQStoreException e) + { + exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + @Override + public void dtxSetTimeout(Session session, DtxSetTimeout method) + { + try + { + ((ServerSession)session).setTimeoutDtx(method.getXid(), method.getTimeout()); + } + catch(UnknownDtxBranchException e) + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, e.getMessage()); + } + } @Override public void executionSync(final Session ssn, final ExecutionSync sync) @@ -465,9 +706,9 @@ public class ServerSessionDelegate extends SessionDelegate } else { - if(!exchange.getTypeShortString().toString().equals(method.getType())) + if(!exchange.getTypeShortString().toString().equals(method.getType()) && (method.getType() != null && method.getType().length() > 0)) { - exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot redeclare with a different exchange type"); + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Attempt to redeclare exchange: " + exchangeName + " of type " + exchange.getTypeShortString() + " to " + method.getType() +"."); } } @@ -476,48 +717,96 @@ public class ServerSessionDelegate extends SessionDelegate { if (exchange == null) { - ExchangeRegistry exchangeRegistry = getExchangeRegistry(session); - ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory(); + if(exchangeName.startsWith("amq.")) + { + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, + "Attempt to declare exchange: " + exchangeName + + " which begins with reserved prefix 'amq.'."); + } + else if(exchangeName.startsWith("qpid.")) + { + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, + "Attempt to declare exchange: " + exchangeName + + " which begins with reserved prefix 'qpid.'."); + } + else + { + ExchangeRegistry exchangeRegistry = getExchangeRegistry(session); + ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory(); - try - { + try + { + + exchange = exchangeFactory.createExchange(method.getExchange(), + method.getType(), + method.getDurable(), + method.getAutoDelete()); + + String alternateExchangeName = method.getAlternateExchange(); + boolean validAlternate; + if(alternateExchangeName != null && alternateExchangeName.length() != 0) + { + Exchange alternate = getExchange(session, alternateExchangeName); + if(alternate == null) + { + validAlternate = false; + } + else + { + exchange.setAlternateExchange(alternate); + validAlternate = true; + } + } + else + { + validAlternate = true; + } - exchange = exchangeFactory.createExchange(method.getExchange(), - method.getType(), - method.getDurable(), - method.getAutoDelete()); + if(validAlternate) + { + if (exchange.isDurable()) + { + DurableConfigurationStore store = virtualHost.getDurableConfigurationStore(); + store.createExchange(exchange); + } - String alternateExchangeName = method.getAlternateExchange(); - if(alternateExchangeName != null && alternateExchangeName.length() != 0) + exchangeRegistry.registerExchange(exchange); + } + else + { + exception(session, method, ExecutionErrorCode.NOT_FOUND, + "Unknown alternate exchange " + alternateExchangeName); + } + } + catch(AMQUnknownExchangeType e) { - Exchange alternate = getExchange(session, alternateExchangeName); - exchange.setAlternateExchange(alternate); + exception(session, method, ExecutionErrorCode.NOT_FOUND, "Unknown Exchange Type: " + method.getType()); } - - if (exchange.isDurable()) + catch (AMQException e) { - DurableConfigurationStore store = virtualHost.getDurableConfigurationStore(); - store.createExchange(exchange); + exception(session, method, e, "Cannot declare exchange '" + exchangeName); } - - exchangeRegistry.registerExchange(exchange); - } - catch(AMQUnknownExchangeType e) - { - exception(session, method, ExecutionErrorCode.NOT_FOUND, "Unknown Exchange Type: " + method.getType()); - } - catch (AMQException e) - { - exception(session, method, e, "Cannot declare exchange '" + exchangeName); } } else { if(!exchange.getTypeShortString().toString().equals(method.getType())) { - exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot redeclare with a different exchange type"); + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, + "Attempt to redeclare exchange: " + exchangeName + + " of type " + exchange.getTypeShortString() + + " to " + method.getType() +"."); + } + else if(method.hasAlternateExchange() + && (exchange.getAlternateExchange() == null || + !method.getAlternateExchange().equals(exchange.getAlternateExchange().getName()))) + { + exception(session, method, ExecutionErrorCode.NOT_ALLOWED, + "Attempt to change alternate exchange of: " + exchangeName + + " from " + exchange.getAlternateExchange() + + " to " + method.getAlternateExchange() +"."); } } @@ -710,15 +999,10 @@ public class ServerSessionDelegate extends SessionDelegate { exception(session, method, ExecutionErrorCode.INVALID_ARGUMENT, "Bind not allowed for default exchange"); } -/* - else if (!method.hasBindingKey()) - { - exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "binding-key not set"); - } -*/ else { //TODO - here because of non-compiant python tests + // should raise exception ILLEGAL_ARGUMENT "binding-key not set" if (!method.hasBindingKey()) { method.setBindingKey(method.getQueue()); @@ -739,10 +1023,7 @@ public class ServerSessionDelegate extends SessionDelegate } else { - AMQShortString routingKey = new AMQShortString(method.getBindingKey()); - FieldTable fieldTable = FieldTable.convertToFieldTable(method.getArguments()); - - if (!exchange.isBound(routingKey, fieldTable, queue)) + if (!exchange.isBound(method.getBindingKey(), method.getArguments(), queue)) { try { @@ -854,12 +1135,6 @@ public class ServerSessionDelegate extends SessionDelegate if(method.hasBindingKey()) { - if(method.hasArguments()) - { - FieldTable args = FieldTable.convertToFieldTable(method.getArguments()); - - result.setArgsNotMatched(!exchange.isBound(new AMQShortString(method.getBindingKey()), args, queue)); - } if(queueMatched) { result.setKeyNotMatched(!exchange.isBound(method.getBindingKey(), queue)); @@ -868,23 +1143,28 @@ public class ServerSessionDelegate extends SessionDelegate { result.setKeyNotMatched(!exchange.isBound(method.getBindingKey())); } + + if(method.hasArguments()) + { + result.setArgsNotMatched(!exchange.isBound(result.getKeyNotMatched() ? null : method.getBindingKey(), method.getArguments(), queueMatched ? queue : null)); + } + } else if (method.hasArguments()) { - // TODO - + result.setArgsNotMatched(!exchange.isBound(null, method.getArguments(), queueMatched ? queue : null)); } - result.setQueueNotMatched(!exchange.isBound(queue)); - } else if(exchange != null && method.hasBindingKey()) { + result.setKeyNotMatched(!exchange.isBound(method.getBindingKey())); + if(method.hasArguments()) { - // TODO + result.setArgsNotMatched(!exchange.isBound(result.getKeyNotMatched() ? null : method.getBindingKey(), method.getArguments(), queue)); } - result.setKeyNotMatched(!exchange.isBound(method.getBindingKey())); + } @@ -893,11 +1173,15 @@ public class ServerSessionDelegate extends SessionDelegate { if(method.hasArguments()) { - // TODO + result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments(), null)); } result.setKeyNotMatched(!exchange.isBound(method.getBindingKey())); } + else if(exchange != null && method.hasArguments()) + { + result.setArgsNotMatched(!exchange.isBound(null, method.getArguments(), null)); + } session.executionResult((int) method.getId(), result); @@ -1141,6 +1425,10 @@ public class ServerSessionDelegate extends SessionDelegate { exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session"); } + else if(queue.isExclusive() && queue.getExclusiveOwningSession() != null && queue.getExclusiveOwningSession() != session) + { + exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session"); + } else if (method.getIfEmpty() && !queue.isEmpty()) { exception(session, method, ExecutionErrorCode.PRECONDITION_FAILED, "Queue " + queueName + " not empty"); @@ -1287,8 +1575,9 @@ public class ServerSessionDelegate extends SessionDelegate ServerSession serverSession = (ServerSession)session; - serverSession.unregisterSubscriptions(); + serverSession.stopSubscriptions(); serverSession.onClose(); + serverSession.unregisterSubscriptions(); } @Override diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AlreadyKnownDtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AlreadyKnownDtxException.java new file mode 100644 index 0000000000..faa4ec592f --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AlreadyKnownDtxException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class AlreadyKnownDtxException extends DtxException +{ + public AlreadyKnownDtxException(Xid id) + { + super("Xid " + id + " cannot be started as it is already known"); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java index 7e238aeadc..a062c6732f 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.txn; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.AMQStoreException; import org.apache.qpid.server.message.EnqueableMessage; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java index ad2a299108..597797b5f8 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java @@ -20,11 +20,8 @@ */ package org.apache.qpid.server.txn; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.AMQStoreException; import org.apache.qpid.server.message.EnqueableMessage; @@ -33,6 +30,9 @@ import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.store.MessageStore; +import java.util.Collection; +import java.util.List; + /** * An implementation of ServerTransaction where each enqueue/dequeue * operation takes place within it own transaction. diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java new file mode 100644 index 0000000000..36f5f7b58f --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java @@ -0,0 +1,246 @@ +/* + * + * 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.txn; + +import org.apache.qpid.server.message.EnqueableMessage; +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.virtualhost.VirtualHost; +import org.apache.qpid.transport.Xid; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class DistributedTransaction implements ServerTransaction +{ + + private final AutoCommitTransaction _autoCommitTransaction; + + private volatile MessageStore.Transaction _transaction; + + private long _txnStartTime = 0L; + + private DtxBranch _branch; + private AMQSessionModel _session; + private VirtualHost _vhost; + + + public DistributedTransaction(AMQSessionModel session, MessageStore store, VirtualHost vhost) + { + _session = session; + _vhost = vhost; + _autoCommitTransaction = new AutoCommitTransaction(vhost.getMessageStore()); + } + + public long getTransactionStartTime() + { + return _txnStartTime; + } + + public void addPostTransactionAction(Action postTransactionAction) + { + if(_branch != null) + { + _branch.addPostTransactionAcion(postTransactionAction); + } + else + { + _autoCommitTransaction.addPostTransactionAction(postTransactionAction); + } + } + + public void dequeue(BaseQueue queue, EnqueableMessage message, Action postTransactionAction) + { + if(_branch != null) + { + _branch.dequeue(queue, message); + _branch.addPostTransactionAcion(postTransactionAction); + } + else + { + _autoCommitTransaction.dequeue(queue, message, postTransactionAction); + } + } + + public void dequeue(Collection<QueueEntry> messages, Action postTransactionAction) + { + if(_branch != null) + { + for(QueueEntry entry : messages) + { + _branch.dequeue(entry.getQueue(), entry.getMessage()); + } + _branch.addPostTransactionAcion(postTransactionAction); + } + else + { + _autoCommitTransaction.dequeue(messages, postTransactionAction); + } + } + + public void enqueue(BaseQueue queue, EnqueableMessage message, Action postTransactionAction) + { + if(_branch != null) + { + _branch.enqueue(queue, message); + _branch.addPostTransactionAcion(postTransactionAction); + enqueue(Collections.singletonList(queue), message, postTransactionAction, System.currentTimeMillis()); + } + else + { + _autoCommitTransaction.enqueue(queue, message, postTransactionAction); + } + } + + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, + Action postTransactionAction, long currentTime) + { + if(_branch != null) + { + for(BaseQueue queue : queues) + { + _branch.enqueue(queue, message); + } + _branch.addPostTransactionAcion(postTransactionAction); + } + else + { + _autoCommitTransaction.enqueue(queues, message, postTransactionAction, currentTime); + } + } + + public void commit() + { + throw new IllegalStateException("Cannot call tx.commit() on a distributed transaction"); + } + + public void commit(Runnable immediatePostTransactionAction) + { + throw new IllegalStateException("Cannot call tx.commit() on a distributed transaction"); + } + + public void rollback() + { + throw new IllegalStateException("Cannot call tx.rollback() on a distributed transaction"); + } + + public boolean isTransactional() + { + return _branch != null; + } + + public void start(Xid id, boolean join, boolean resume) + throws UnknownDtxBranchException, AlreadyKnownDtxException, JoinAndResumeDtxException + { + if(join && resume) + { + throw new JoinAndResumeDtxException(id); + } + + DtxBranch branch = _vhost.getDtxRegistry().getBranch(id); + + if(branch == null) + { + if(join || resume) + { + throw new UnknownDtxBranchException(id); + } + branch = new DtxBranch(id,_vhost.getMessageStore(), _vhost); + if(_vhost.getDtxRegistry().registerBranch(branch)) + { + _branch = branch; + branch.associateSession(_session); + } + else + { + throw new AlreadyKnownDtxException(id); + } + } + else + { + if(join) + { + branch.associateSession(_session); + } + else if(resume) + { + branch.resumeSession(_session); + } + else + { + throw new AlreadyKnownDtxException(id); + } + _branch = branch; + } + } + + public void end(Xid id, boolean fail, boolean suspend) + throws UnknownDtxBranchException, NotAssociatedDtxException, SuspendAndFailDtxException, TimeoutDtxException + { + DtxBranch branch = _vhost.getDtxRegistry().getBranch(id); + + if(suspend && fail) + { + branch.disassociateSession(_session); + _branch = null; + throw new SuspendAndFailDtxException(id); + } + + + if(branch == null) + { + throw new UnknownDtxBranchException(id); + } + else + { + if(!branch.isAssociated(_session)) + { + throw new NotAssociatedDtxException(id); + } + if(branch.expired() || branch.getState() == DtxBranch.State.TIMEDOUT) + { + branch.disassociateSession(_session); + throw new TimeoutDtxException(id); + } + + if(suspend) + { + branch.suspendSession(_session); + } + else + { + if(fail) + { + branch.setState(DtxBranch.State.ROLLBACK_ONLY); + } + branch.disassociateSession(_session); + } + + _branch = null; + + } + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java new file mode 100644 index 0000000000..99bb639261 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java @@ -0,0 +1,348 @@ +/* + * + * 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.txn; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQStoreException; +import org.apache.qpid.server.message.EnqueableMessage; +import org.apache.qpid.server.protocol.AMQSessionModel; +import org.apache.qpid.server.queue.BaseQueue; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.virtualhost.VirtualHost; +import org.apache.qpid.transport.Xid; + +public class DtxBranch +{ + private static final Logger _logger = Logger.getLogger(DtxBranch.class); + + private final Xid _xid; + private final List<ServerTransaction.Action> _postTransactionActions = new ArrayList<ServerTransaction.Action>(); + private State _state = State.ACTIVE; + private long _timeout; + private Map<AMQSessionModel, State> _associatedSessions = new HashMap<AMQSessionModel, State>(); + private final List<Record> _enqueueRecords = new ArrayList<Record>(); + private final List<Record> _dequeueRecords = new ArrayList<Record>(); + + private MessageStore.Transaction _transaction; + private long _expiration; + private VirtualHost _vhost; + private ScheduledFuture<?> _timeoutFuture; + private MessageStore _store; + + + public enum State + { + ACTIVE, + PREPARED, + TIMEDOUT, + SUSPENDED, + FORGOTTEN, + HEUR_COM, + HEUR_RB, + ROLLBACK_ONLY + } + + + public DtxBranch(Xid xid, MessageStore store, VirtualHost vhost) + { + _xid = xid; + _store = store; + _vhost = vhost; + } + + public Xid getXid() + { + return _xid; + } + + public State getState() + { + return _state; + } + + public void setState(State state) + { + _state = state; + } + + public long getTimeout() + { + return _timeout; + } + + public void setTimeout(long timeout) + { + if(_timeoutFuture != null) + { + _timeoutFuture.cancel(false); + } + _timeout = timeout; + _expiration = timeout == 0 ? 0 : System.currentTimeMillis() + timeout; + + if(_timeout == 0) + { + _timeoutFuture = null; + } + else + { + _timeoutFuture = _vhost.scheduleTask(_timeout, new Runnable() + { + public void run() + { + setState(State.TIMEDOUT); + try + { + rollback(); + } + catch (AMQStoreException e) + { + _logger.error("Unexpected error when attempting to rollback XA transaction ("+ + _xid + ") due to timeout", e); + throw new RuntimeException(e); + } + } + }); + } + } + + public boolean expired() + { + return _timeout != 0 && _expiration < System.currentTimeMillis(); + } + + public synchronized boolean isAssociated(AMQSessionModel session) + { + return _associatedSessions.containsKey(session); + } + + public synchronized boolean hasAssociatedSessions() + { + return !_associatedSessions.isEmpty(); + } + + + public synchronized boolean hasAssociatedActiveSessions() + { + if(hasAssociatedSessions()) + { + for(State state : _associatedSessions.values()) + { + if(state != State.SUSPENDED) + { + return true; + } + } + } + return false; + } + + public synchronized void clearAssociations() + { + _associatedSessions.clear(); + } + + synchronized boolean associateSession(AMQSessionModel associatedSession) + { + return _associatedSessions.put(associatedSession, State.ACTIVE) != null; + } + + synchronized boolean disassociateSession(AMQSessionModel associatedSession) + { + return _associatedSessions.remove(associatedSession) != null; + } + + public synchronized boolean resumeSession(AMQSessionModel session) + { + if(_associatedSessions.containsKey(session) && _associatedSessions.get(session) == State.SUSPENDED) + { + _associatedSessions.put(session, State.ACTIVE); + return true; + } + return false; + } + + public synchronized boolean suspendSession(AMQSessionModel session) + { + if(_associatedSessions.containsKey(session) && _associatedSessions.get(session) == State.ACTIVE) + { + _associatedSessions.put(session, State.SUSPENDED); + return true; + } + return false; + } + + public void prepare() throws AMQStoreException + { + + MessageStore.Transaction txn = _store.newTransaction(); + txn.recordXid(_xid.getFormat(), + _xid.getGlobalId(), + _xid.getBranchId(), + _enqueueRecords.toArray(new Record[_enqueueRecords.size()]), + _dequeueRecords.toArray(new Record[_dequeueRecords.size()])); + txn.commitTran(); + + prePrepareTransaction(); + } + + public synchronized void rollback() throws AMQStoreException + { + if(_timeoutFuture != null) + { + _timeoutFuture.cancel(false); + _timeoutFuture = null; + } + + + if(_transaction != null) + { + // prepare has previously been called + + MessageStore.Transaction txn = _store.newTransaction(); + txn.removeXid(_xid.getFormat(), _xid.getGlobalId(), _xid.getBranchId()); + txn.commitTran(); + + _transaction.abortTran(); + } + + for(ServerTransaction.Action action : _postTransactionActions) + { + action.onRollback(); + } + _postTransactionActions.clear(); + } + + public void commit() throws AMQStoreException + { + if(_timeoutFuture != null) + { + _timeoutFuture.cancel(false); + _timeoutFuture = null; + } + + if(_transaction == null) + { + prePrepareTransaction(); + } + else + { + _transaction.removeXid(_xid.getFormat(), _xid.getGlobalId(), _xid.getBranchId()); + } + _transaction.commitTran(); + + for(ServerTransaction.Action action : _postTransactionActions) + { + action.postCommit(); + } + _postTransactionActions.clear(); + } + + public void prePrepareTransaction() throws AMQStoreException + { + _transaction = _store.newTransaction(); + + for(Record enqueue : _enqueueRecords) + { + if(enqueue.isDurable()) + { + _transaction.enqueueMessage(enqueue.getQueue(), enqueue.getMessage()); + } + } + + + for(Record enqueue : _dequeueRecords) + { + if(enqueue.isDurable()) + { + _transaction.dequeueMessage(enqueue.getQueue(), enqueue.getMessage()); + } + } + } + + + public void addPostTransactionAcion(ServerTransaction.Action postTransactionAction) + { + _postTransactionActions.add(postTransactionAction); + } + + + public void dequeue(BaseQueue queue, EnqueableMessage message) + { + _dequeueRecords.add(new Record(queue, message)); + } + + + public void enqueue(BaseQueue queue, EnqueableMessage message) + { + _enqueueRecords.add(new Record(queue, message)); + } + + private static final class Record implements MessageStore.Transaction.Record + { + private final BaseQueue _queue; + private final EnqueableMessage _message; + + public Record(BaseQueue queue, EnqueableMessage message) + { + _queue = queue; + _message = message; + } + + public BaseQueue getQueue() + { + return _queue; + } + + public EnqueableMessage getMessage() + { + return _message; + } + + public boolean isDurable() + { + return _message.isPersistent() && _queue.isDurable(); + } + } + + + public void close() + { + if(_transaction != null) + { + try + { + _state = null; + _transaction.abortTran(); + } + catch(AMQStoreException e) + { + _logger.error("Error while closing XA branch", e); + } + } + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxException.java new file mode 100644 index 0000000000..d18d0cb68b --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxException.java @@ -0,0 +1,44 @@ +/* + * + * 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.txn; + +public class DtxException extends Exception +{ + public DtxException() + { + } + + public DtxException(String message) + { + super(message); + } + + public DtxException(String message, Throwable cause) + { + super(message, cause); + } + + public DtxException(Throwable cause) + { + super(cause); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxNotSelectedException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxNotSelectedException.java new file mode 100644 index 0000000000..c1289b1fdd --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxNotSelectedException.java @@ -0,0 +1,30 @@ +/* + * + * 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.txn; + +public class DtxNotSelectedException extends DtxException +{ + public DtxNotSelectedException() + { + super("Distribution transactions have not been selected on this session"); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java new file mode 100644 index 0000000000..5c54c1164f --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java @@ -0,0 +1,333 @@ +/* + * + * 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.txn; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.qpid.AMQStoreException; +import org.apache.qpid.server.protocol.AMQSessionModel; +import org.apache.qpid.transport.Xid; + +public class DtxRegistry +{ + private final Map<ComparableXid, DtxBranch> _branches = new HashMap<ComparableXid, DtxBranch>(); + + + private static final class ComparableXid + { + private final Xid _xid; + + private ComparableXid(Xid xid) + { + _xid = xid; + } + + @Override + public boolean equals(Object o) + { + if(this == o) + { + return true; + } + if(o == null || getClass() != o.getClass()) + { + return false; + } + + ComparableXid that = (ComparableXid) o; + + return compareBytes(_xid.getBranchId(), that._xid.getBranchId()) + && compareBytes(_xid.getGlobalId(), that._xid.getGlobalId()); + } + + private static boolean compareBytes(byte[] a, byte[] b) + { + if(a.length != b.length) + { + return false; + } + for(int i = 0; i < a.length; i++) + { + if(a[i] != b[i]) + { + return false; + } + } + return true; + } + + + @Override + public int hashCode() + { + int result = 0; + for(int i = 0; i < _xid.getGlobalId().length; i++) + { + result = 31 * result + (int) _xid.getGlobalId()[i]; + } + for(int i = 0; i < _xid.getBranchId().length; i++) + { + result = 31 * result + (int) _xid.getBranchId()[i]; + } + + return result; + } + } + + public synchronized DtxBranch getBranch(Xid xid) + { + return _branches.get(new ComparableXid(xid)); + } + + public synchronized boolean registerBranch(DtxBranch branch) + { + ComparableXid xid = new ComparableXid(branch.getXid()); + if(!_branches.containsKey(xid)) + { + _branches.put(xid, branch); + return true; + } + return false; + } + + synchronized boolean unregisterBranch(DtxBranch branch) + { + return (_branches.remove(new ComparableXid(branch.getXid())) != null); + } + + public void commit(Xid id, boolean onePhase) + throws IncorrectDtxStateException, UnknownDtxBranchException, AMQStoreException, RollbackOnlyDtxException, TimeoutDtxException + { + DtxBranch branch = getBranch(id); + if(branch != null) + { + synchronized (branch) + { + if(!branch.hasAssociatedActiveSessions()) + { + branch.clearAssociations(); + + if(branch.expired() || branch.getState() == DtxBranch.State.TIMEDOUT) + { + unregisterBranch(branch); + throw new TimeoutDtxException(id); + } + else if(branch.getState() == DtxBranch.State.ROLLBACK_ONLY) + { + throw new RollbackOnlyDtxException(id); + } + else if(onePhase && branch.getState() == DtxBranch.State.PREPARED) + { + throw new IncorrectDtxStateException("Cannot call one-phase commit on a prepared branch", id); + } + else if(!onePhase && branch.getState() != DtxBranch.State.PREPARED) + { + throw new IncorrectDtxStateException("Cannot call two-phase commit on a non-prepared branch", + id); + } + branch.commit(); + branch.setState(DtxBranch.State.FORGOTTEN); + unregisterBranch(branch); + } + else + { + throw new IncorrectDtxStateException("Branch was still associated with a session", id); + } + } + } + else + { + throw new UnknownDtxBranchException(id); + } + } + + public synchronized void prepare(Xid id) + throws UnknownDtxBranchException, + IncorrectDtxStateException, AMQStoreException, RollbackOnlyDtxException, TimeoutDtxException + { + DtxBranch branch = getBranch(id); + if(branch != null) + { + synchronized (branch) + { + if(!branch.hasAssociatedActiveSessions()) + { + branch.clearAssociations(); + + if(branch.expired() || branch.getState() == DtxBranch.State.TIMEDOUT) + { + unregisterBranch(branch); + throw new TimeoutDtxException(id); + } + else if(branch.getState() != DtxBranch.State.ACTIVE + && branch.getState() != DtxBranch.State.ROLLBACK_ONLY) + { + throw new IncorrectDtxStateException("Cannot prepare a transaction in state " + + branch.getState(), id); + } + else + { + branch.prepare(); + branch.setState(DtxBranch.State.PREPARED); + } + } + else + { + throw new IncorrectDtxStateException("Branch still has associated sessions", id); + } + } + } + else + { + throw new UnknownDtxBranchException(id); + } + } + + public void rollback(Xid id) + throws IncorrectDtxStateException, + UnknownDtxBranchException, + AMQStoreException, TimeoutDtxException + { + + DtxBranch branch = getBranch(id); + if(branch != null) + { + synchronized (branch) + { + if(branch.expired() || branch.getState() == DtxBranch.State.TIMEDOUT) + { + unregisterBranch(branch); + throw new TimeoutDtxException(id); + } + if(!branch.hasAssociatedActiveSessions()) + { + branch.clearAssociations(); + branch.rollback(); + branch.setState(DtxBranch.State.FORGOTTEN); + unregisterBranch(branch); + } + else + { + throw new IncorrectDtxStateException("Branch was still associated with a session", id); + } + } + } + else + { + throw new UnknownDtxBranchException(id); + } + } + + + public void forget(Xid id) throws UnknownDtxBranchException, IncorrectDtxStateException + { + DtxBranch branch = getBranch(id); + if(branch != null) + { + synchronized (branch) + { + if(!branch.hasAssociatedSessions()) + { + if(branch.getState() != DtxBranch.State.HEUR_COM && branch.getState() != DtxBranch.State.HEUR_RB) + { + throw new IncorrectDtxStateException("Branch should not be forgotten - " + + "it is not heuristically complete", id); + } + branch.setState(DtxBranch.State.FORGOTTEN); + unregisterBranch(branch); + } + else + { + throw new IncorrectDtxStateException("Branch was still associated with a session", id); + } + } + } + else + { + throw new UnknownDtxBranchException(id); + } + } + + public long getTimeout(Xid id) throws UnknownDtxBranchException + { + DtxBranch branch = getBranch(id); + if(branch != null) + { + return branch.getTimeout(); + } + else + { + throw new UnknownDtxBranchException(id); + } + } + + public void setTimeout(Xid id, long timeout) throws UnknownDtxBranchException + { + DtxBranch branch = getBranch(id); + if(branch != null) + { + branch.setTimeout(timeout); + } + else + { + throw new UnknownDtxBranchException(id); + } + } + + public synchronized List<Xid> recover() + { + List<Xid> inDoubt = new ArrayList<Xid>(); + for(DtxBranch branch : _branches.values()) + { + if(branch.getState() == DtxBranch.State.PREPARED) + { + inDoubt.add(branch.getXid()); + } + } + return inDoubt; + } + + public synchronized void endAssociations(AMQSessionModel session) + { + for(DtxBranch branch : _branches.values()) + { + if(branch.isAssociated(session)) + { + branch.setState(DtxBranch.State.ROLLBACK_ONLY); + branch.disassociateSession(session); + } + } + } + + + public synchronized void close() + { + for(DtxBranch branch : _branches.values()) + { + branch.close(); + } + _branches.clear(); + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/IncorrectDtxStateException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/IncorrectDtxStateException.java new file mode 100644 index 0000000000..45f094e4b9 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/IncorrectDtxStateException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class IncorrectDtxStateException extends DtxException +{ + public IncorrectDtxStateException(String message, Xid id) + { + super(message + " (xid: " + id + ")"); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/JoinAndResumeDtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/JoinAndResumeDtxException.java new file mode 100644 index 0000000000..a25e5a4ed6 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/JoinAndResumeDtxException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class JoinAndResumeDtxException extends DtxException +{ + public JoinAndResumeDtxException(Xid id) + { + super("Cannot start a branch with both join and resume set " + id); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java index 34bac0411e..9b61f7543f 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java @@ -20,9 +20,8 @@ package org.apache.qpid.server.txn; * */ -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.apache.qpid.AMQException; import org.apache.qpid.server.message.EnqueableMessage; @@ -31,8 +30,9 @@ import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.store.MessageStore; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; /** * A concrete implementation of ServerTransaction where enqueue/dequeue diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NotAssociatedDtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NotAssociatedDtxException.java new file mode 100644 index 0000000000..de070546a7 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NotAssociatedDtxException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class NotAssociatedDtxException extends DtxException +{ + public NotAssociatedDtxException(Xid id) + { + super("Xid " + id + " not associated with the current session"); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/RollbackOnlyDtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/RollbackOnlyDtxException.java new file mode 100644 index 0000000000..6cf12d8631 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/RollbackOnlyDtxException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class RollbackOnlyDtxException extends DtxException +{ + public RollbackOnlyDtxException(Xid id) + { + super("Transaction " + id + " may only be rolled back"); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/SuspendAndFailDtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/SuspendAndFailDtxException.java new file mode 100644 index 0000000000..228844fd63 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/SuspendAndFailDtxException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class SuspendAndFailDtxException extends DtxException +{ +public SuspendAndFailDtxException(Xid id) +{ + super("Cannot end a branch with both suspend and fail set " + id); +} +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TimeoutDtxException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TimeoutDtxException.java new file mode 100644 index 0000000000..50f7708d8a --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TimeoutDtxException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class TimeoutDtxException extends DtxException +{ + public TimeoutDtxException(Xid id) + { + super("Transaction " + id + " has timed-out and may only be rolled back"); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/UnknownDtxBranchException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/UnknownDtxBranchException.java new file mode 100644 index 0000000000..c23e518365 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/UnknownDtxBranchException.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.txn; + +import org.apache.qpid.transport.Xid; + +public class UnknownDtxBranchException extends DtxException +{ + public UnknownDtxBranchException(Xid id) + { + super("Unknown xid " + id); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/CircularBuffer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/CircularBuffer.java deleted file mode 100644 index e730e2f3c3..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/CircularBuffer.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.util; - -import java.util.Iterator; - -import org.apache.log4j.Logger; - -public class CircularBuffer implements Iterable -{ - - private static final Logger _logger = Logger.getLogger(CircularBuffer.class); - - private final Object[] _log; - private int _size; - private int _index; - - public CircularBuffer(int size) - { - _log = new Object[size]; - } - - public void add(Object o) - { - _log[_index++] = o; - _size = Math.min(_size+1, _log.length); - if(_index >= _log.length) - { - _index = 0; - } - } - - public Object get(int i) - { - if(i >= _log.length) - { - throw new ArrayIndexOutOfBoundsException(i); - } - return _log[index(i)]; - } - - public int size() { - return _size; - } - - public Iterator iterator() - { - return new Iterator() - { - private int i = 0; - - public boolean hasNext() - { - return i < _size; - } - - public Object next() - { - return get(i++); - } - - public void remove() - { - throw new UnsupportedOperationException(); - } - }; - } - - public String toString() - { - StringBuilder s = new StringBuilder(); - boolean first = true; - for(Object o : this) - { - if(!first) - { - s.append(", "); - } - else - { - first = false; - } - s.append(o); - } - return s.toString(); - } - - public void dump() - { - for(Object o : this) - { - _logger.info(o); - } - } - - int index(int i) - { - return _size == _log.length ? (_index + i) % _log.length : i; - } - - public static void main(String[] artgv) - { - String[] items = new String[]{ - "A","B","C","D","E","F","G","H","I","J","K" - }; - CircularBuffer buffer = new CircularBuffer(5); - for(String s : items) - { - buffer.add(s); - _logger.info(buffer); - } - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/LoggingProxy.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/LoggingProxy.java deleted file mode 100644 index eda97e0ed2..0000000000 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/LoggingProxy.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.util; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Arrays; - -/** - * Dynamic proxy that records invocations in a fixed size circular buffer, - * dumping details on hitting an exception. - * <p> - * Useful in debugging. - * <p> - */ -public class LoggingProxy implements InvocationHandler -{ - private final Object _target; - private final CircularBuffer _log; - - public LoggingProxy(Object target, int size) - { - _target = target; - _log = new CircularBuffer(size); - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable - { - try - { - entered(method, args); - Object result = method.invoke(_target, args); - returned(method, result); - return result; - } - catch(InvocationTargetException e) - { - dump(); - throw e.getTargetException(); - } - } - - void dump() - { - _log.dump(); - } - - CircularBuffer getBuffer() - { - return _log; - } - - private synchronized void entered(Method method, Object[] args) - { - if (args == null) - { - _log.add(Thread.currentThread() + ": " + method.getName() + "() entered"); - } - else - { - _log.add(Thread.currentThread() + ": " + method.getName() + "(" + Arrays.toString(args) + ") entered"); - } - } - - private synchronized void returned(Method method, Object result) - { - if (method.getReturnType() == Void.TYPE) - { - _log.add(Thread.currentThread() + ": " + method.getName() + "() returned"); - } - else - { - _log.add(Thread.currentThread() + ": " + method.getName() + "() returned " + result); - } - } - - public Object getProxy(Class... c) - { - return Proxy.newProxyInstance(_target.getClass().getClassLoader(), c, this); - } - - public int getBufferSize() { - return _log.size(); - } -} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java index ebace95f65..523bafb8e1 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java @@ -21,13 +21,14 @@ package org.apache.qpid.server.virtualhost; import org.apache.log4j.Logger; + import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.logging.actors.AbstractActor; import org.apache.qpid.server.logging.actors.CurrentActor; public abstract class HouseKeepingTask implements Runnable { - Logger _logger = Logger.getLogger(this.getClass()); + private Logger _logger = Logger.getLogger(this.getClass()); private VirtualHost _virtualHost; @@ -59,7 +60,7 @@ public abstract class HouseKeepingTask implements Runnable { execute(); } - catch (Throwable e) + catch (Exception e) { _logger.warn(this.getClass().getSimpleName() + " throw exception: " + e, e); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java index 767474d5ae..cb7f213f06 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java @@ -20,10 +20,10 @@ */
package org.apache.qpid.server.virtualhost;
-import java.io.IOException;
-
import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute;
+import java.io.IOException;
+
/**
* The management interface exposed to allow management of a virtualHost
*/
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index 41a5471a64..4b586db628 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.virtualhost; import java.util.Map; 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; @@ -37,10 +37,10 @@ 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.StatisticsGatherer; 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 { @@ -60,8 +60,6 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo DurableConfigurationStore getDurableConfigurationStore(); - AuthenticationManager getAuthenticationManager(); - SecurityManager getSecurityManager(); void close(); @@ -97,7 +95,11 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo ConfigStore getConfigStore(); + DtxRegistry getDtxRegistry(); + void removeBrokerConnection(BrokerLink brokerLink); LinkRegistry getLinkRegistry(String remoteContainerId); + + ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java index 51892d965a..0e965472d5 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java @@ -20,43 +20,47 @@ */ package org.apache.qpid.server.virtualhost; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQStoreException; +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.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.QueueEntry; 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.StoredMessage; import org.apache.qpid.server.store.TransactionLogRecoveryHandler; import org.apache.qpid.server.store.TransactionLogResource; -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.exchange.Exchange; -import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.messages.TransactionLogMessages; -import org.apache.qpid.server.message.AMQMessage; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.AMQException; - -import org.apache.log4j.Logger; +import org.apache.qpid.server.txn.DtxBranch; +import org.apache.qpid.server.txn.DtxRegistry; +import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.transport.Xid; +import org.apache.qpid.transport.util.Functions; import org.apache.qpid.util.ByteBufferInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; - -import java.util.List; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; -import java.util.TreeMap; -import java.util.UUID; - public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHandler, ConfigurationRecoveryHandler.QueueRecoveryHandler, ConfigurationRecoveryHandler.ExchangeRecoveryHandler, @@ -65,7 +69,8 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa MessageStoreRecoveryHandler, MessageStoreRecoveryHandler.StoredMessageRecoveryHandler, TransactionLogRecoveryHandler, - TransactionLogRecoveryHandler.QueueEntryRecoveryHandler + TransactionLogRecoveryHandler.QueueEntryRecoveryHandler, + TransactionLogRecoveryHandler.DtxRecordRecoveryHandler { private static final Logger _logger = Logger.getLogger(VirtualHostConfigRecoveryHandler.class); @@ -78,7 +83,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa private MessageStore _store; private final Map<String, Integer> _queueRecoveries = new TreeMap<String, Integer>(); - private Map<Long, ServerMessage> _recoveredMessages = new HashMap<Long, ServerMessage>(); + private Map<Long, AbstractServerMessageImpl> _recoveredMessages = new HashMap<Long, AbstractServerMessageImpl>(); private Map<Long, StoredMessage> _unusedMessages = new HashMap<Long, StoredMessage>(); @@ -160,7 +165,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa public void message(StoredMessage message) { - ServerMessage serverMessage; + AbstractServerMessageImpl serverMessage; switch(message.getMetaData().getType()) { case META_DATA_0_8: @@ -173,9 +178,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa throw new RuntimeException("Unknown message type retrieved from store " + message.getMetaData().getClass()); } - //_logger.debug("Recovered message with id " + serverMessage); - - _recoveredMessages.put(message.getMessageNumber(), serverMessage); _unusedMessages.put(message.getMessageNumber(), message); } @@ -198,6 +200,164 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa { } + public void dtxRecord(long format, byte[] globalId, byte[] branchId, + MessageStore.Transaction.Record[] enqueues, + MessageStore.Transaction.Record[] dequeues) + { + Xid id = new Xid(format, globalId, branchId); + DtxRegistry dtxRegistry = _virtualHost.getDtxRegistry(); + DtxBranch branch = dtxRegistry.getBranch(id); + if(branch == null) + { + branch = new DtxBranch(id, _store, _virtualHost); + dtxRegistry.registerBranch(branch); + } + for(MessageStore.Transaction.Record record : enqueues) + { + final AMQQueue queue = _virtualHost.getQueueRegistry().getQueue(record.getQueue().getResourceName()); + if(queue != null) + { + final long messageId = record.getMessage().getMessageNumber(); + final AbstractServerMessageImpl message = _recoveredMessages.get(messageId); + _unusedMessages.remove(messageId); + + if(message != null) + { + message.incrementReference(); + + branch.enqueue(queue,message); + + branch.addPostTransactionAcion(new ServerTransaction.Action() + { + + public void postCommit() + { + try + { + + queue.enqueue(message, true, null); + message.decrementReference(); + } + catch (AMQException e) + { + _logger.error("Unable to enqueue message " + message.getMessageNumber() + " into " + + "queue " + queue.getName() + " (from XA transaction)", e); + throw new RuntimeException(e); + } + } + + public void onRollback() + { + message.decrementReference(); + } + }); + } + else + { + StringBuilder xidString = xidAsString(id); + String messageNumberString = String.valueOf(message.getMessageNumber()); + CurrentActor.get().message(_logSubject, + TransactionLogMessages.XA_INCOMPLETE_MESSAGE(xidString.toString(), + messageNumberString)); + + } + + } + else + { + StringBuilder xidString = xidAsString(id); + CurrentActor.get().message(_logSubject, + TransactionLogMessages.XA_INCOMPLETE_QUEUE(xidString.toString(), + record.getQueue().getResourceName())); + + } + } + for(MessageStore.Transaction.Record record : dequeues) + { + final AMQQueue queue = _virtualHost.getQueueRegistry().getQueue(record.getQueue().getResourceName()); + if(queue != null) + { + final long messageId = record.getMessage().getMessageNumber(); + final AbstractServerMessageImpl message = _recoveredMessages.get(messageId); + _unusedMessages.remove(messageId); + + if(message != null) + { + final QueueEntry entry = queue.getMessageOnTheQueue(messageId); + + entry.acquire(); + + branch.dequeue(queue, message); + + branch.addPostTransactionAcion(new ServerTransaction.Action() + { + + public void postCommit() + { + entry.discard(); + } + + public void onRollback() + { + entry.release(); + } + }); + } + else + { + StringBuilder xidString = xidAsString(id); + String messageNumberString = String.valueOf(message.getMessageNumber()); + CurrentActor.get().message(_logSubject, + TransactionLogMessages.XA_INCOMPLETE_MESSAGE(xidString.toString(), + messageNumberString)); + + } + + } + else + { + StringBuilder xidString = xidAsString(id); + CurrentActor.get().message(_logSubject, + TransactionLogMessages.XA_INCOMPLETE_QUEUE(xidString.toString(), + queue.getName())); + } + + } + + try + { + branch.setState(DtxBranch.State.PREPARED); + branch.prePrepareTransaction(); + } + catch (AMQStoreException e) + { + _logger.error("Unexpected database exception when attempting to prepare a recovered XA transaction " + + xidAsString(id), e); + throw new RuntimeException(e); + } + } + + private static StringBuilder xidAsString(Xid id) + { + return new StringBuilder("(") + .append(id.getFormat()) + .append(',') + .append(Functions.str(id.getGlobalId())) + .append(',') + .append(Functions.str(id.getBranchId())) + .append(')'); + } + + public void completeDtxRecordRecovery() + { + for(StoredMessage m : _unusedMessages.values()) + { + _logger.warn("Message id " + m.getMessageNumber() + " in store, but not in any queue - removing...."); + m.remove(); + } + CurrentActor.get().message(_logSubject, TransactionLogMessages.RECOVERY_COMPLETE(null, false)); + } + private static final class ProcessAction { private final AMQQueue _queue; @@ -354,15 +514,9 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa } - public void completeQueueEntryRecovery() + public DtxRecordRecoveryHandler completeQueueEntryRecovery() { - for(StoredMessage m : _unusedMessages.values()) - { - _logger.warn("Message id " + m.getMessageNumber() + " in store, but not in any queue - removing...."); - m.remove(); - } - for(Map.Entry<String,Integer> entry : _queueRecoveries.entrySet()) { CurrentActor.get().message(_logSubject, TransactionLogMessages.RECOVERED(entry.getValue(), entry.getKey())); @@ -370,7 +524,9 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa CurrentActor.get().message(_logSubject, TransactionLogMessages.RECOVERY_COMPLETE(entry.getKey(), true)); } - CurrentActor.get().message(_logSubject, TransactionLogMessages.RECOVERY_COMPLETE(null, false)); + + + return this; } private static class DummyMessage implements EnqueableMessage diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java index a4a3633af7..9a0606f47a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java @@ -20,21 +20,11 @@ */ package org.apache.qpid.server.virtualhost; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; - +import java.util.concurrent.ScheduledFuture; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; + import org.apache.qpid.AMQException; import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.AMQShortString; @@ -73,14 +63,25 @@ import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.ApplicationRegistry; 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.ConfigurationRecoveryHandler; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.txn.DtxRegistry; import org.apache.qpid.server.virtualhost.plugins.VirtualHostPlugin; import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + public class VirtualHostImpl implements VirtualHost { private static final Logger _logger = Logger.getLogger(VirtualHostImpl.class); @@ -97,11 +98,11 @@ public class VirtualHostImpl implements VirtualHost private MessageStore _messageStore; - protected VirtualHostMBean _virtualHostMBean; + private DtxRegistry _dtxRegistry; - private AMQBrokerManagerMBean _brokerMBean; + private VirtualHostMBean _virtualHostMBean; - private final AuthenticationManager _authenticationManager; + private AMQBrokerManagerMBean _brokerMBean; private SecurityManager _securityManager; @@ -121,6 +122,7 @@ public class VirtualHostImpl implements VirtualHost private static final int HOUSEKEEPING_SHUTDOWN_TIMEOUT = 5; private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>(); + public IConnectionRegistry getConnectionRegistry() { return _connectionRegistry; @@ -191,6 +193,7 @@ public class VirtualHostImpl implements VirtualHost _broker = _appRegistry.getBroker(); _configuration = hostConfig; _name = _configuration.getName(); + _dtxRegistry = new DtxRegistry(); _id = _appRegistry.getConfigStore().createId(); @@ -241,7 +244,6 @@ public class VirtualHostImpl implements VirtualHost initialiseMessageStore(hostConfig); } - _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager(); _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean); _brokerMBean.register(); @@ -260,54 +262,9 @@ public class VirtualHostImpl implements VirtualHost { if (period != 0L) { - class VirtualHostHouseKeepingTask extends HouseKeepingTask - { - public VirtualHostHouseKeepingTask(VirtualHost vhost) - { - super(vhost); - } - public void execute() - { - for (AMQQueue q : _queueRegistry.getQueues()) - { - _logger.debug("Checking message status for queue: " - + q.getName()); - try - { - q.checkMessageStatus(); - } - catch (Exception e) - { - _logger.error("Exception in housekeeping for queue: " - + q.getNameShortString().toString(), e); - //Don't throw exceptions as this will stop the - // house keeping task from running. - } - } - for (AMQConnectionModel connection : getConnectionRegistry().getConnections()) - { - _logger.debug("Checking for long running open transactions on connection " + connection); - for (AMQSessionModel session : connection.getSessionModels()) - { - _logger.debug("Checking for long running open transactions on session " + session); - try - { - session.checkTransactionStatus(_configuration.getTransactionTimeoutOpenWarn(), - _configuration.getTransactionTimeoutOpenClose(), - _configuration.getTransactionTimeoutIdleWarn(), - _configuration.getTransactionTimeoutIdleClose()); - } - catch (Exception e) - { - _logger.error("Exception in housekeeping for connection: " + connection.toString(), e); - } - } - } - } - } - scheduleHouseKeepingTask(period, new VirtualHostHouseKeepingTask(this)); + scheduleHouseKeepingTask(period, new VirtualHostHouseKeepingTask()); Map<String, VirtualHostPluginFactory> plugins = ApplicationRegistry.getInstance().getPluginManager().getVirtualHostPlugins(); @@ -340,6 +297,53 @@ public class VirtualHostImpl implements VirtualHost } } + private class VirtualHostHouseKeepingTask extends HouseKeepingTask + { + public VirtualHostHouseKeepingTask() + { + super(VirtualHostImpl.this); + } + + public void execute() + { + for (AMQQueue q : _queueRegistry.getQueues()) + { + _logger.debug("Checking message status for queue: " + + q.getName()); + try + { + q.checkMessageStatus(); + } + catch (Exception e) + { + _logger.error("Exception in housekeeping for queue: " + + q.getNameShortString().toString(), e); + //Don't throw exceptions as this will stop the + // house keeping task from running. + } + } + for (AMQConnectionModel connection : getConnectionRegistry().getConnections()) + { + _logger.debug("Checking for long running open transactions on connection " + connection); + for (AMQSessionModel session : connection.getSessionModels()) + { + _logger.debug("Checking for long running open transactions on session " + session); + try + { + session.checkTransactionStatus(_configuration.getTransactionTimeoutOpenWarn(), + _configuration.getTransactionTimeoutOpenClose(), + _configuration.getTransactionTimeoutIdleWarn(), + _configuration.getTransactionTimeoutIdleClose()); + } + catch (Exception e) + { + _logger.error("Exception in housekeeping for connection: " + connection.toString(), e); + } + } + } + } + } + /** * Allow other broker components to register a HouseKeepingTask * @@ -352,6 +356,11 @@ public class VirtualHostImpl implements VirtualHost TimeUnit.MILLISECONDS); } + public ScheduledFuture<?> scheduleTask(long delay, Runnable task) + { + return _houseKeepingTasks.schedule(task, delay, TimeUnit.MILLISECONDS); + } + public long getHouseKeepingTaskCount() { return _houseKeepingTasks.getTaskCount(); @@ -575,11 +584,6 @@ public class VirtualHostImpl implements VirtualHost return _durableConfigurationStore; } - public AuthenticationManager getAuthenticationManager() - { - return _authenticationManager; - } - public SecurityManager getSecurityManager() { return _securityManager; @@ -618,6 +622,11 @@ public class VirtualHostImpl implements VirtualHost } } + if(_dtxRegistry != null) + { + _dtxRegistry.close(); + } + //Close MessageStore if (_messageStore != null) { @@ -796,6 +805,11 @@ public class VirtualHostImpl implements VirtualHost return getApplicationRegistry().getConfigStore(); } + public DtxRegistry getDtxRegistry() + { + return _dtxRegistry; + } + /** * Temporary Startup RT class to record the creation of persistent queues / exchanges. * @@ -805,11 +819,11 @@ public class VirtualHostImpl implements VirtualHost */ private static class StartupRoutingTable implements DurableConfigurationStore { - public List<Exchange> exchange = new LinkedList<Exchange>(); - public List<CreateQueueTuple> queue = new LinkedList<CreateQueueTuple>(); - public List<CreateBindingTuple> bindings = new LinkedList<CreateBindingTuple>(); - public List<BrokerLink> links = new LinkedList<BrokerLink>(); - public List<Bridge> bridges = new LinkedList<Bridge>(); + private List<Exchange> exchange = new LinkedList<Exchange>(); + private List<CreateQueueTuple> queue = new LinkedList<CreateQueueTuple>(); + private List<CreateBindingTuple> bindings = new LinkedList<CreateBindingTuple>(); + private List<BrokerLink> links = new LinkedList<BrokerLink>(); + private List<Bridge> bridges = new LinkedList<Bridge>(); public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception { @@ -876,8 +890,8 @@ public class VirtualHostImpl implements VirtualHost private static class CreateQueueTuple { - public AMQQueue queue; - public FieldTable arguments; + private AMQQueue queue; + private FieldTable arguments; public CreateQueueTuple(AMQQueue queue, FieldTable arguments) { @@ -888,10 +902,10 @@ public class VirtualHostImpl implements VirtualHost private static class CreateBindingTuple { - public AMQQueue queue; - public FieldTable arguments; - public Exchange exchange; - public AMQShortString routingKey; + private AMQQueue queue; + private FieldTable arguments; + private Exchange exchange; + private AMQShortString routingKey; public CreateBindingTuple(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java index 32d0c4c4d1..ef621a166a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java @@ -21,8 +21,8 @@ package org.apache.qpid.server.virtualhost;
import org.apache.qpid.common.Closeable;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.configuration.ConfigStore;
+import org.apache.qpid.server.registry.ApplicationRegistry;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java index 12206013eb..12886f400a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java @@ -20,19 +20,18 @@ */ package org.apache.qpid.server.virtualhost.plugins; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - 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.AbstractExchange; 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. * @@ -93,7 +92,7 @@ public class ConfiguredQueueBindingListener implements BindingListener /** * Lookup and return the cache of configured {@link AMQQueue}s. * - * Note that when accessing the cached queues, the {@link Iterator} is not thread safe + * 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. * diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java index 248b3b2143..2c6705bb3b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java @@ -19,21 +19,20 @@ */ package org.apache.qpid.server.virtualhost.plugins; -import java.util.Set; -import java.util.concurrent.TimeUnit; - 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.configuration.plugins.ConfigurationPlugin; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.plugins.Plugin; 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; @@ -61,7 +60,7 @@ public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin * virtual host to record all the configured queues in a cache for processing by the housekeeping * thread. * - * @see Plugin#configure(ConfigurationPlugin) + * @see org.apache.qpid.server.plugins.Plugin#configure(ConfigurationPlugin) */ public void configure(ConfigurationPlugin config) { @@ -98,7 +97,7 @@ public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin if (policy == null) { // We would only expect to see this during shutdown - _logger.warn("No slow consumer policy for queue " + q.getName()); + getLogger().warn("No slow consumer policy for queue " + q.getName()); } else { @@ -110,7 +109,7 @@ public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin catch (Exception e) { // Don't throw exceptions as this will stop the house keeping task from running. - _logger.error("Exception in SlowConsumersDetection for queue: " + q.getName(), e); + getLogger().error("Exception in SlowConsumersDetection for queue: " + q.getName(), e); } } @@ -139,9 +138,9 @@ public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin { if (config != null) { - if (_logger.isInfoEnabled()) + if (getLogger().isInfoEnabled()) { - _logger.info("Retrieved Queue(" + q.getName() + ") Config:" + config); + getLogger().info("Retrieved Queue(" + q.getName() + ") Config:" + config); } int count = q.getMessageCount(); @@ -157,12 +156,12 @@ public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin ((count > 0) && q.getOldestMessageArrivalTime() >= config.getMessageAge()))) { - if (_logger.isDebugEnabled()) + if (getLogger().isDebugEnabled()) { - _logger.debug("Detected Slow Consumer on Queue(" + q.getName() + ")"); - _logger.debug("Queue Count:" + q.getMessageCount() + ":" + config.getMessageCount()); - _logger.debug("Queue Depth:" + q.getQueueDepth() + ":" + config.getDepth()); - _logger.debug("Queue Arrival:" + q.getOldestMessageArrivalTime() + ":" + config.getMessageAge()); + 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; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java index 3798f47f0b..191f8041d2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.virtualhost.plugins; import org.apache.log4j.Logger; + import org.apache.qpid.server.virtualhost.HouseKeepingTask; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -28,7 +29,7 @@ import java.util.concurrent.TimeUnit; public abstract class VirtualHostHouseKeepingPlugin extends HouseKeepingTask implements VirtualHostPlugin { - protected final Logger _logger = Logger.getLogger(getClass()); + private final Logger _logger = Logger.getLogger(getClass()); public VirtualHostHouseKeepingPlugin(VirtualHost vhost) { @@ -51,4 +52,10 @@ public abstract class VirtualHostHouseKeepingPlugin extends HouseKeepingTask imp * @see java.util.concurrent.TimeUnit for valid value. */ public abstract TimeUnit getTimeUnit(); + + + protected Logger getLogger() + { + return _logger; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java index 1886c2d01d..35f6228ab9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java @@ -20,10 +20,9 @@ */ package org.apache.qpid.server.virtualhost.plugins; -import java.util.concurrent.TimeUnit; - import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.virtualhost.VirtualHost; + +import java.util.concurrent.TimeUnit; public interface VirtualHostPlugin extends Runnable, Plugin { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java index 6028f63fdb..f2f61f204e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java @@ -22,10 +22,10 @@ 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.SlowConsumerDetectionPolicyConfiguration; import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; import org.apache.qpid.server.exchange.TopicExchange; import org.apache.qpid.server.logging.actors.CurrentActor; @@ -37,7 +37,7 @@ import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFa public class TopicDeletePolicy implements SlowConsumerPolicyPlugin { - Logger _logger = Logger.getLogger(TopicDeletePolicy.class); + private Logger _logger = Logger.getLogger(TopicDeletePolicy.class); private TopicDeletePolicyConfiguration _configuration; public static class TopicDeletePolicyFactory implements SlowConsumerPolicyPluginFactory diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java index 7dfd22c733..48158b7dff 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java @@ -20,14 +20,15 @@ */ package org.apache.qpid.server.virtualhost.plugins.policies; -import java.util.Arrays; -import java.util.List; - 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 { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java index 3d3c7b6cc6..cd833c89c4 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java @@ -14,9 +14,9 @@ * "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. + * under the License. + * * - * */ package org.apache.qpid.tools.security; @@ -26,8 +26,12 @@ import java.nio.charset.Charset; import java.security.DigestException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; + import org.apache.commons.codec.binary.Base64; +/** + * Utility to generate user:encodedPassword string for use in md5passwd + */ public class Passwd { public static void main(String args[]) throws NoSuchAlgorithmException, DigestException, IOException @@ -63,5 +67,4 @@ public class Passwd String encodedStr = new String(encoded, Charset.forName("utf-8")); return userName + ":" + encodedStr; } - } |