diff options
author | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
commit | 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 (patch) | |
tree | 2a890e1df09e5b896a9b4168a7b22648f559a1f2 /java/broker/src/main | |
parent | 172d9b2a16cfb817bbe632d050acba7e31401cd2 (diff) | |
download | qpid-python-9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919.tar.gz |
Update from trunk r1375509 through r1450773asyncstore
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker/src/main')
286 files changed, 10702 insertions, 19169 deletions
diff --git a/java/broker/src/main/java/broker.bnd b/java/broker/src/main/java/broker.bnd index 4e799a1609..bf338543f7 100755 --- a/java/broker/src/main/java/broker.bnd +++ b/java/broker/src/main/java/broker.bnd @@ -17,7 +17,7 @@ # under the License. # -ver: 0.19.0 +ver: 0.21.0 Bundle-SymbolicName: qpid-broker Bundle-Version: ${ver} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java b/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java deleted file mode 100644 index 27ab580642..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/ManagementExchange.java +++ /dev/null @@ -1,586 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ExchangeConfigType; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.ExchangeReferrer; -import org.apache.qpid.server.exchange.ExchangeType; -import org.apache.qpid.server.exchange.topic.TopicExchangeResult; -import org.apache.qpid.server.exchange.topic.TopicMatcherResult; -import org.apache.qpid.server.exchange.topic.TopicNormalizer; -import org.apache.qpid.server.exchange.topic.TopicParser; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.HouseKeepingTask; -import org.apache.qpid.server.virtualhost.VirtualHost; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.atomic.AtomicLong; - -public class ManagementExchange implements Exchange, QMFService.Listener -{ - private static final AMQShortString QPID_MANAGEMENT = new AMQShortString("qpid.management"); - private static final AMQShortString QPID_MANAGEMENT_TYPE = new AMQShortString("management"); - - private VirtualHost _virtualHost; - - private final TopicParser _parser = new TopicParser(); - - private final Map<AMQShortString, TopicExchangeResult> _topicExchangeResults = - new ConcurrentHashMap<AMQShortString, TopicExchangeResult>(); - - private final Set<Binding> _bindingSet = new CopyOnWriteArraySet<Binding>(); - private UUID _id; - private UUID _qmfId; - private static final String AGENT_BANK = "0"; - - private int _bindingCountHigh; - private final AtomicLong _msgReceived = new AtomicLong(); - private final AtomicLong _bytesReceived = new AtomicLong(); - - private final CopyOnWriteArrayList<BindingListener> _listeners = new CopyOnWriteArrayList<Exchange.BindingListener>(); - - //TODO : persist creation time - private long _createTime = System.currentTimeMillis(); - - - private class ManagementQueue implements BaseQueue - { - private final UUID QUEUE_ID = UUIDGenerator.generateRandomUUID(); - private final String NAME_AS_STRING = "##__mgmt_pseudo_queue__##" + QUEUE_ID.toString(); - private final AMQShortString NAME_AS_SHORT_STRING = new AMQShortString(NAME_AS_STRING); - - public void enqueue(ServerMessage message) throws AMQException - { - long size = message.getSize(); - - ByteBuffer buf = ByteBuffer.allocate((int) size); - - int offset = 0; - - while(offset < size) - { - offset += message.getContent(buf,offset); - } - - buf.flip(); - QMFCommandDecoder commandDecoder = new QMFCommandDecoder(getQMFService(),buf); - QMFCommand cmd; - while((cmd = commandDecoder.decode()) != null) - { - cmd.process(_virtualHost, message); - } - - } - - public void enqueue(ServerMessage message, boolean sync, PostEnqueueAction action) throws AMQException - { - enqueue(message); - } - - public void enqueue(ServerMessage message, PostEnqueueAction action) throws AMQException - { - enqueue(message); - } - - public boolean isDurable() - { - return false; - } - - public AMQShortString getNameShortString() - { - return NAME_AS_SHORT_STRING; - } - - @Override - public UUID getId() - { - return QUEUE_ID; - } - } - - - private final ManagementQueue _mgmtQueue = new ManagementQueue(); - - public ManagementExchange() - { - } - - public static final ExchangeType<ManagementExchange> TYPE = new ExchangeType<ManagementExchange>() - { - - public AMQShortString getName() - { - return QPID_MANAGEMENT_TYPE; - } - - public Class<ManagementExchange> getExchangeClass() - { - return ManagementExchange.class; - } - - public ManagementExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - ManagementExchange exch = new ManagementExchange(); - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return QPID_MANAGEMENT; - } - }; - - - public AMQShortString getNameShortString() - { - return QPID_MANAGEMENT; - } - - public AMQShortString getTypeShortString() - { - return QPID_MANAGEMENT_TYPE; - } - - public void initialise(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete) - throws AMQException - { - if(!QPID_MANAGEMENT.equals(name)) - { - throw new AMQException("Can't create more than one Management exchange"); - } - _virtualHost = host; - _id = id; - _virtualHost.scheduleHouseKeepingTask(_virtualHost.getBroker().getManagementPublishInterval(), new UpdateTask(_virtualHost)); - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); - getQMFService().addListener(this); - } - - public UUID getId() - { - return _id; - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ExchangeConfigType getConfigType() - { - return ExchangeConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _virtualHost; - } - - public boolean isDurable() - { - return true; - } - - public VirtualHost getVirtualHost() - { - return _virtualHost; - } - - public String getName() - { - return QPID_MANAGEMENT.toString(); - } - - public ExchangeType getType() - { - return TYPE; - } - - public boolean isAutoDelete() - { - return false; - } - - public int getTicket() - { - return 0; - } - - public void close() throws AMQException - { - getConfigStore().removeConfiguredObject(this); - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - - public synchronized void addBinding(final Binding b) - { - - if(_bindingSet.add(b)) - { - AMQShortString routingKey = TopicNormalizer.normalize(new AMQShortString(b.getBindingKey())); - - TopicExchangeResult result = _topicExchangeResults.get(routingKey); - if(result == null) - { - result = new TopicExchangeResult(); - result.addUnfilteredQueue(b.getQueue()); - _parser.addBinding(routingKey, result); - _topicExchangeResults.put(routingKey,result); - } - else - { - result.addUnfilteredQueue(b.getQueue()); - } - - result.addBinding(b); - } - - for(BindingListener listener : _listeners) - { - listener.bindingAdded(this, b); - } - - if(_bindingSet.size() > _bindingCountHigh) - { - _bindingCountHigh = _bindingSet.size(); - } - - String bindingKey = b.getBindingKey(); - - if(bindingKey.startsWith("schema.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#.")) - { - publishAllSchema(); - } - if(bindingKey.startsWith("console.") || bindingKey.startsWith("*.") || bindingKey.startsWith("#.")) - { - publishAllConsole(); - } - - } - - void publishAllConsole() - { - QMFService qmfService = getQMFService(); - - long sampleTime = System.currentTimeMillis(); - - for(QMFPackage pkg : qmfService.getSupportedSchemas()) - { - for(QMFClass qmfClass : pkg.getClasses()) - { - Collection<QMFObject> qmfObjects = qmfService.getObjects(qmfClass); - - publishObjectsToConsole(sampleTime, qmfObjects); - } - - } - - } - - private QMFService getQMFService() - { - return _virtualHost.getApplicationRegistry().getQMFService(); - } - - void publishObjectsToConsole(final long sampleTime, - final Collection<QMFObject> qmfObjects) - { - if(!qmfObjects.isEmpty() && hasBindings()) - { - QMFClass qmfClass = qmfObjects.iterator().next().getQMFClass(); - ArrayList<QMFCommand> commands = new ArrayList<QMFCommand>(); - - - for(QMFObject obj : qmfObjects) - { - commands.add(obj.asConfigInfoCmd(sampleTime)); - commands.add(obj.asInstrumentInfoCmd(sampleTime)); - } - - publishToConsole(qmfClass, commands); - } - } - - private void publishToConsole(final QMFClass qmfClass, final ArrayList<QMFCommand> commands) - { - if(!commands.isEmpty() && hasBindings()) - { - String routingKey = "console.obj.1." + AGENT_BANK + "." + qmfClass.getPackage().getName() + "." + qmfClass.getName(); - QMFMessage message = new QMFMessage(routingKey,commands.toArray(new QMFCommand[commands.size()])); - - Collection<TopicMatcherResult> results = _parser.parse(new AMQShortString(routingKey)); - HashSet<AMQQueue> queues = new HashSet<AMQQueue>(); - for(TopicMatcherResult result : results) - { - TopicExchangeResult res = (TopicExchangeResult)result; - - for(Binding b : res.getBindings()) - { - b.incrementMatches(); - } - - queues.addAll(((TopicExchangeResult)result).getUnfilteredQueues()); - } - for(AMQQueue queue : queues) - { - try - { - queue.enqueue(message); - } - catch (AMQException e) - { - throw new RuntimeException(e); - } - } - } - } - - void publishAllSchema() - { - - } - - public synchronized void removeBinding(final Binding binding) - { - if(_bindingSet.remove(binding)) - { - AMQShortString bindingKey = TopicNormalizer.normalize(new AMQShortString(binding.getBindingKey())); - TopicExchangeResult result = _topicExchangeResults.get(bindingKey); - result.removeBinding(binding); - result.removeUnfilteredQueue(binding.getQueue()); - } - - for(BindingListener listener : _listeners) - { - listener.bindingRemoved(this, binding); - } - } - - public synchronized Collection<Binding> getBindings() - { - return new ArrayList<Binding>(_bindingSet); - } - - public ArrayList<BaseQueue> route(InboundMessage message) - { - ArrayList<BaseQueue> queues = new ArrayList<BaseQueue>(1); - _msgReceived.incrementAndGet(); - _bytesReceived.addAndGet(message.getSize()); - queues.add(_mgmtQueue); - return queues; - } - - public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue) - { - return false; //TODO - } - - public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(AMQShortString routingKey, AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(AMQShortString routingKey) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean hasBindings() - { - return !_bindingSet.isEmpty(); - } - - public boolean isBound(String bindingKey, AMQQueue queue) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public boolean isBound(String bindingKey) - { - return false; //To change body of implemented methods use File | Settings | File Templates. - } - - public void addCloseTask(final Task task) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void removeCloseTask(final Task task) - { - //To change body of implemented methods use File | Settings | File Templates. - } - - - - public Exchange getAlternateExchange() - { - return null; - } - - public Map<String, Object> getArguments() - { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - - public void setAlternateExchange(Exchange exchange) - { - - } - - public void removeReference(ExchangeReferrer exchange) - { - } - - public void addReference(ExchangeReferrer exchange) - { - } - - public boolean hasReferrers() - { - return true; - } - - - - private class UpdateTask extends HouseKeepingTask - { - public UpdateTask(VirtualHost vhost) - { - super(vhost); - } - - public void execute() - { - publishAllConsole(); - publishAllSchema(); - } - - } - - public void objectCreated(final QMFObject obj) - { - publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj)); - } - - public void objectDeleted(final QMFObject obj) - { - publishObjectsToConsole(System.currentTimeMillis(), Collections.singleton(obj)); - } - - public long getBindingCount() - { - return getBindings().size(); - } - - public long getBindingCountHigh() - { - return _bindingCountHigh; - } - - public long getMsgReceives() - { - return _msgReceived.get(); - } - - public long getMsgRoutes() - { - return getMsgReceives(); - } - - public long getMsgDrops() - { - return 0l; - } - - public long getByteReceives() - { - return _bytesReceived.get(); - } - - public long getByteRoutes() - { - return getByteReceives(); - } - - public long getByteDrops() - { - return 0l; - } - - public long getCreateTime() - { - return _createTime; - } - - public void addBindingListener(final BindingListener listener) - { - _listeners.add(listener); - } - - public void removeBindingListener(final BindingListener listener) - { - _listeners.remove(listener); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java deleted file mode 100644 index 69284abc48..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerRequestCommand.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.List; - -public class QMFBrokerRequestCommand extends QMFCommand -{ - - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - - public QMFBrokerRequestCommand(QMFCommandHeader header, BBDecoder buf) - { - super(header); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String queueName = message.getMessageHeader().getReplyToRoutingKey(); - - _qmfLogger.debug("Execute: " + this); - - QMFCommand[] commands = new QMFCommand[2]; - commands[0] = new QMFBrokerResponseCommand(this, virtualHost); - commands[1] = new QMFCommandCompletionCommand(this); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - for(QMFCommand cmd : commands) - { - QMFMessage responseMessage = new QMFMessage(queueName, cmd); - - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java deleted file mode 100644 index 7d566567a1..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClass.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -abstract public class QMFClass -{ - - - public enum Type - { - OBJECT((byte)1), - EVENT((byte)2); - - private final byte _value; - - Type(byte value) - { - _value = value; - } - - public byte getValue() - { - return _value; - } - } - - private final Type _type; - private QMFPackage _package; - private final String _name; - private byte[] _schemaHash; - - private Map<String, QMFProperty> _properties = new LinkedHashMap<String, QMFProperty>(); - private Map<String, QMFStatistic> _statistics = new LinkedHashMap<String, QMFStatistic>(); - private Map<String, QMFMethod> _methods = new LinkedHashMap<String, QMFMethod>(); - - - - public QMFClass(Type type, String name, byte[] schemaHash, List<QMFProperty> properties, - List<QMFStatistic> statistics, List<QMFMethod> methods) - { - this(type, name, schemaHash); - setProperties(properties); - setStatistics(statistics); - setMethods(methods); - } - - - public QMFClass(Type type, String name, byte[] schemaHash) - - { - _type = type; - _name = name; - _schemaHash = schemaHash; - - } - - protected void setProperties(List<QMFProperty> properties) - { - for(QMFProperty prop : properties) - { - _properties.put(prop.getName(), prop); - } - } - - protected void setStatistics(List<QMFStatistic> statistics) - { - for(QMFStatistic stat : statistics) - { - _statistics.put(stat.getName(), stat); - } - } - - - protected void setMethods(List<QMFMethod> methods) - { - for(QMFMethod method : methods) - { - _methods.put(method.getName(), method); - } - } - - public void setPackage(QMFPackage aPackage) - { - _package = aPackage; - for(QMFProperty prop : _properties.values()) - { - prop.setQMFClass(this); - } - // TODO Statisics, Methods - } - - public Type getType() - { - return _type; - } - - public QMFPackage getPackage() - { - return _package; - } - - public String getName() - { - return _name; - } - - public byte[] getSchemaHash() - { - return _schemaHash; - } - - public Collection<QMFProperty> getProperties() - { - return _properties.values(); - } - - public Collection<QMFStatistic> getStatistics() - { - return _statistics.values(); - } - - public Collection<QMFMethod> getMethods() - { - return _methods.values(); - } - - public QMFMethod getMethod(String methodName) - { - return _methods.get(methodName); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java deleted file mode 100644 index 5676bb7306..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassQueryCommand.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.Collection; -import java.util.List; - -public class QMFClassQueryCommand extends QMFCommand -{ - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - - private final String _package; - - public QMFClassQueryCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - _package = decoder.readStr8(); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - _qmfLogger.debug("Execute: " + this); - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - QMFPackage qmfPackage = service.getPackage(_package); - Collection<QMFClass> qmfClasses = qmfPackage.getClasses(); - - QMFCommand[] commands = new QMFCommand[ qmfClasses.size() + 1 ]; - - int i = 0; - for(QMFClass qmfClass : qmfClasses) - { - commands[i++] = new QMFClassIndicationCommand(this, qmfClass); - } - commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this); - - - for(QMFCommand cmd : commands) - { - - - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - - @Override - public String toString() - { - return "QMFClassQueryCommand{" + - "package='" + _package + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java deleted file mode 100644 index 397ad4090e..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandCompletionCommand.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFCommandCompletionCommand extends QMFCommand -{ - - private final CompletionCode _status; - private final String _text; - - public QMFCommandCompletionCommand(QMFCommand command) - { - this(command, CompletionCode.OK, ""); - } - public QMFCommandCompletionCommand(QMFCommand command, CompletionCode status, String text) - { - super( new QMFCommandHeader(command.getHeader().getVersion(), - command.getHeader().getSeq(), - QMFOperation.COMMAND_COMPLETION)); - - _status = status; - _text = text; - } - - - @Override - public void encode(BBEncoder encoder) - { - super.encode(encoder); - encoder.writeInt32(_status.ordinal()); - encoder.writeStr8(_text); - } - - @Override - public String toString() - { - return "QMFCommandCompletionCommand{" + - "status=" + _status + - ",text='" + _text + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java deleted file mode 100644 index ac036dfa19..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandDecoder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.BBDecoder; - -import java.nio.ByteBuffer; - -public class QMFCommandDecoder -{ - private BBDecoder _decoder; - - - private static final QMFOperation[] OP_CODES = new QMFOperation[256]; - private final QMFService _qmfService; - - static - { - for(QMFOperation op : QMFOperation.values()) - { - OP_CODES[op.getOpcode()] = op; - } - } - - public QMFCommandDecoder(final QMFService qmfService, ByteBuffer buf) - { - _qmfService = qmfService; - _decoder = new BBDecoder(); - _decoder.init(buf); - } - - public QMFCommand decode() - { - if(_decoder.hasRemaining()) - { - QMFCommandHeader header = readQMFHeader(); - - switch(header.getOperation()) - { - case BROKER_REQUEST: - return new QMFBrokerRequestCommand(header, _decoder); - case PACKAGE_QUERY: - return new QMFPackageQueryCommand(header, _decoder); - case CLASS_QUERY: - return new QMFClassQueryCommand(header, _decoder); - case SCHEMA_REQUEST: - return new QMFSchemaRequestCommand(header, _decoder); - case METHOD_REQUEST: - return new QMFMethodRequestCommand(header, _decoder, _qmfService); - case GET_QUERY: - return new QMFGetQueryCommand(header, _decoder); - default: - System.out.println("Unknown command"); - - } - - return null; - } - else - { - return null; - } - } - - private QMFCommandHeader readQMFHeader() - { - if(_decoder.readInt8() == (byte) 'A' - && _decoder.readInt8() == (byte) 'M') - { - byte version = _decoder.readInt8(); - short opCode = _decoder.readUint8(); - int seq = _decoder.readInt32(); - - return new QMFCommandHeader(version, seq, OP_CODES[opCode]); - - } - return null; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java deleted file mode 100644 index c4d771317f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommandHeader.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFCommandHeader -{ - private final byte _version; - private final int _seq; - - private final QMFOperation _operation; - - public QMFCommandHeader(byte version, int seq, QMFOperation operation) - { - _version = version; - _seq = seq; - _operation = operation; - } - - public byte getVersion() - { - return _version; - } - - public int getSeq() - { - return _seq; - } - - public QMFOperation getOperation() - { - return _operation; - } - - public void encode(BBEncoder encoder) - { - encoder.writeUint8((short)'A'); - encoder.writeUint8((short)'M'); - encoder.writeInt8(_version); - encoder.writeUint8((short)_operation.getOpcode()); - encoder.writeInt32(_seq); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java deleted file mode 100644 index b1f958d4ba..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFGetQueryCommand.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public class QMFGetQueryCommand extends QMFCommand -{ - - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - private String _className; - private String _packageName; - private UUID _objectId; - - public QMFGetQueryCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - - Map<String, Object> _map = decoder.readMap(); - _className = (String) _map.get("_class"); - _packageName = (String) _map.get("_package"); - byte[] objectIdBytes = (byte[]) _map.get("_objectId"); - - if(objectIdBytes != null) - { - long msb = 0; - long lsb = 0; - - for (int i = 0; i != 8; i++) - { - msb = (msb << 8) | (objectIdBytes[i] & 0xff); - } - for (int i = 8; i != 16; i++) - { - lsb = (lsb << 8) | (objectIdBytes[i] & 0xff); - } - _objectId = new UUID(msb, lsb); - } - else - { - _objectId = null; - } - - - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - _qmfLogger.debug("Execute: " + this); - - List<QMFCommand> commands = new ArrayList<QMFCommand>(); - final long sampleTime = System.currentTimeMillis() * 1000000l; - - Collection<QMFPackage> packages; - - if(_packageName != null && _packageName.length() != 0) - { - QMFPackage qmfPackage = service.getPackage(_packageName); - if(qmfPackage == null) - { - packages = Collections.EMPTY_LIST; - } - else - { - packages = Collections.singleton(qmfPackage); - } - } - else - { - packages = service.getSupportedSchemas(); - } - - for(QMFPackage qmfPackage : packages) - { - - Collection<QMFClass> qmfClasses; - - if(_className != null && _className.length() != 0) - { - QMFClass qmfClass = qmfPackage.getQMFClass(_className); - if(qmfClass == null) - { - qmfClasses = Collections.EMPTY_LIST; - } - else - { - qmfClasses = Collections.singleton(qmfClass); - } - } - else - { - qmfClasses = qmfPackage.getClasses(); - } - - - for(QMFClass qmfClass : qmfClasses) - { - Collection<QMFObject> objects; - - if(_objectId != null) - { - QMFObject obj = service.getObjectById(qmfClass, _objectId); - if(obj == null) - { - objects = Collections.EMPTY_LIST; - } - else - { - objects = Collections.singleton(obj); - } - } - else - { - objects = service.getObjects(qmfClass); - } - - for(QMFObject object : objects) - { - - commands.add(object.asGetQueryResponseCmd(this, sampleTime)); - } - } - - - } - - - commands.add( new QMFCommandCompletionCommand(this)); - - - for(QMFCommand cmd : commands) - { - - _qmfLogger.debug("Respond: " + cmd); - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - @Override - public String toString() - { - return "QMFGetQueryCommand{" + - "packageName='" + _packageName + '\'' + - ", className='" + _className + '\'' + - ", objectId=" + _objectId + - '}'; - } -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java deleted file mode 100644 index 1b173c7e11..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMessage.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import java.util.Collection; -import java.util.Collections; -import org.apache.commons.lang.NotImplementedException; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.message.AMQMessageHeader; -import org.apache.qpid.server.message.InboundMessage; -import org.apache.qpid.server.message.MessageReference; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.transport.codec.BBEncoder; - -import java.nio.ByteBuffer; -import java.util.Set; - -public class QMFMessage implements ServerMessage, InboundMessage, AMQMessageHeader -{ - - private ByteBuffer _content; - private String _routingKey; - - public QMFMessage(String routingKey, QMFCommand command) - { - this(routingKey, new QMFCommand[] { command }); - } - - - public QMFMessage(String routingKey, QMFCommand[] commands) - { - _routingKey = routingKey; - BBEncoder encoder = new BBEncoder(256); - - for(QMFCommand cmd : commands) - { - cmd.encode(encoder); - } - - - _content = encoder.buffer(); - } - - public String getRoutingKey() - { - return _routingKey; - } - - public AMQShortString getRoutingKeyShortString() - { - return AMQShortString.valueOf(_routingKey); - } - - public AMQMessageHeader getMessageHeader() - { - return this; - } - - public StoredMessage getStoredMessage() - { - throw new NotImplementedException(); - } - - public boolean isPersistent() - { - return false; - } - - public boolean isRedelivered() - { - return false; - } - - public long getSize() - { - return _content.limit(); - } - - public boolean isImmediate() - { - return false; - } - - public String getCorrelationId() - { - return null; - } - - public long getExpiration() - { - return 0; - } - - public String getUserId() - { - return null; - } - - public String getAppId() - { - return null; - } - - public String getMessageId() - { - return null; - } - - public String getMimeType() - { - return null; - } - - public String getEncoding() - { - return null; - } - - public byte getPriority() - { - return 4; - } - - public long getTimestamp() - { - return 0; - } - - public String getType() - { - return null; - } - - public String getReplyTo() - { - return null; - } - - public String getReplyToExchange() - { - return null; - } - - public String getReplyToRoutingKey() - { - return null; - } - - public Object getHeader(String name) - { - return null; - } - - public boolean containsHeaders(Set<String> names) - { - return false; - } - - @Override - public Collection<String> getHeaderNames() - { - return Collections.EMPTY_SET; - } - - public boolean containsHeader(String name) - { - return false; - } - - public MessageReference newReference() - { - return new QMFMessageReference(this); - } - - public long getMessageNumber() - { - return 0l; - } - - public long getArrivalTime() - { - return 0; - } - - public int getContent(ByteBuffer buf, int offset) - { - ByteBuffer src = _content.duplicate(); - src.position(offset); - src = src.slice(); - int len = src.remaining(); - if(len > buf.remaining()) - { - len = buf.remaining(); - } - - buf.put(src); - - return len; - } - - - public ByteBuffer getContent(int offset, int size) - { - ByteBuffer src = _content.duplicate(); - src.position(offset); - src = src.slice(); - src.limit(size); - return src; - } - - private static class QMFMessageReference extends MessageReference<QMFMessage> - { - public QMFMessageReference(QMFMessage message) - { - super(message); - } - - protected void onReference(QMFMessage message) - { - - } - - protected void onRelease(QMFMessage message) - { - - } - } - - public SessionConfig getSessionConfig() - { - return null; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java deleted file mode 100644 index 1d1cd24724..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethod.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.transport.codec.Encoder; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; - -public abstract class QMFMethod<T extends QMFObject> -{ - private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>(); - private final List<Argument> _arguments = new ArrayList<Argument>(); - - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String REF_PACKAGE = "refPackage"; - private static final String REF_CLASS = "refClass"; - private static final String UNIT = "unit"; - private static final String MIN = "min"; - private static final String MAX = "max"; - private static final String MAX_LENGTH = "maxlen"; - private static final String DESCRIPTION = "desc"; - private static final String DEFAULT = "default"; - private static final String DIRECTION = "dir"; - private static final String ARG_COUNT = "argCount"; - - - - public enum Direction - { - I, - O, - IO; - } - - public class Argument - { - private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>(); - - public Argument(String name, QMFType type) - { - _map.put(NAME, name); - _map.put(TYPE, type.codeValue()); - } - - public void setRefPackage(String refPackage) - { - _map.put(REF_PACKAGE, refPackage); - } - - public void setRefClass(String refClass) - { - _map.put(REF_CLASS, refClass); - } - - public void setUnit(String unit) - { - _map.put(UNIT, unit); - } - - public void setMax(Number max) - { - _map.put(MAX, max); - } - - public void setMin(Number min) - { - _map.put(MIN, min); - } - - public void setMaxLength(int len) - { - _map.put(MAX_LENGTH, len); - } - - public void setDefault(Object dflt) - { - _map.put(DEFAULT, dflt); - } - - public void setDescription(String desc) - { - _map.put(DESCRIPTION, desc); - } - - public void setDirection(Direction direction) - { - _map.put(DIRECTION, direction.toString()); - } - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - } - - public String getName() - { - return (String) _map.get(NAME); - } - } - - public QMFMethod(String name, String description) - { - _map.put(NAME, name); - _map.put(ARG_COUNT, 0); - if(description != null) - { - _map.put(DESCRIPTION, description); - } - - } - - abstract public QMFMethodInvocation<T> parse(final BBDecoder decoder); - - protected void addArgument(Argument arg) - { - _arguments.add(arg); - _map.put(ARG_COUNT, _arguments.size()); - } - - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - for(Argument arg : _arguments) - { - arg.encode(encoder); - } - } - - public String getName() - { - return (String) _map.get(NAME); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java deleted file mode 100644 index 5348c2783f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodInvocation.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.qmf; - -public interface QMFMethodInvocation<T extends QMFObject> -{ - QMFMethodResponseCommand execute(T obj, QMFMethodRequestCommand cmd); -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java deleted file mode 100644 index 1a4ce228b5..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodRequestCommand.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.List; -import java.util.UUID; - -public class QMFMethodRequestCommand extends QMFCommand -{ - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - private QMFMethodInvocation _methodInstance; - private QMFObject _object; - - public QMFMethodRequestCommand(final QMFCommandHeader header, final BBDecoder decoder, final QMFService qmfService) - { - super(header); - UUID objectId = decoder.readUuid(); - String packageName = decoder.readStr8(); - String className = decoder.readStr8(); - byte[] hash = decoder.readBin128(); - String methodName = decoder.readStr8(); - - QMFPackage qmfPackage = qmfService.getPackage(packageName); - QMFClass qmfClass = qmfPackage.getQMFClass(className); - _object = qmfService.getObjectById(qmfClass, objectId); - QMFMethod method = qmfClass.getMethod(methodName); - _methodInstance = method.parse(decoder); - - } - - public void process(final VirtualHost virtualHost, final ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String queueName = message.getMessageHeader().getReplyToRoutingKey(); - - QMFCommand[] commands = new QMFCommand[2]; - - _qmfLogger.debug("Execute: " + _methodInstance + " on " + _object); - - commands[0] = _methodInstance.execute(_object, this); - commands[1] = new QMFCommandCompletionCommand(this); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - for(QMFCommand cmd : commands) - { - QMFMessage responseMessage = new QMFMessage(queueName, cmd); - - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java deleted file mode 100644 index 5fea014ad8..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFMethodResponseCommand.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFMethodResponseCommand extends QMFCommand -{ - private CompletionCode _status = null; - private String _msg = null; - - public QMFMethodResponseCommand(final QMFMethodRequestCommand cmd, - CompletionCode status, - String msg) - { - super( new QMFCommandHeader(cmd.getHeader().getVersion(), - cmd.getHeader().getSeq(), - QMFOperation.METHOD_RESPONSE)); - - if(status == null) - { - _status = CompletionCode.OK; - } - else - { - _status = status; - } - - _msg = msg; - } - - public CompletionCode getStatus() - { - return _status; - } - - public String getStatusText() - { - return _msg; - } - - @Override - public void encode(final BBEncoder encoder) - { - super.encode(encoder); - - encoder.writeUint32(_status.ordinal()); - - if(_msg == null) - { - encoder.writeStr16(_status.toString()); - } - else - { - encoder.writeStr16(_msg); - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java deleted file mode 100644 index c3604dca44..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObject.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.qmf; - -import java.util.UUID; - -public abstract class QMFObject<C extends QMFClass, D extends QMFObject.Delegate> -{ - private long _deleteTime; - - public interface Delegate - { - UUID getQMFId(); - long getCreateTime(); - } - - - private D _delegate; - - protected QMFObject(D delegate) - { - _delegate = delegate; - } - - public D getDelegate() - { - return _delegate; - } - - abstract public C getQMFClass(); - - public final UUID getId() - { - return _delegate.getQMFId(); - } - - public final long getCreateTime() - { - return _delegate.getCreateTime(); - } - - public final void setDeleteTime() - { - _deleteTime = System.currentTimeMillis(); - } - - public final long getDeleteTime() - { - return _deleteTime; - } - - - - abstract public QMFCommand asConfigInfoCmd(long sampleTime); - abstract public QMFCommand asInstrumentInfoCmd(long sampleTime); - abstract public QMFCommand asGetQueryResponseCmd(final QMFGetQueryCommand queryCommand, long sampleTime); - - @Override - public String toString() - { - return _delegate.toString(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java deleted file mode 100644 index 6736b5d460..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFOperation.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -public enum QMFOperation -{ - - - BROKER_REQUEST('B'), - BROKER_RESPONSE('b'), // This message contains a broker response, sent from the broker in response to a broker request message. - COMMAND_COMPLETION('z'), // This message is sent to indicate the completion of a request. - CLASS_QUERY('Q'), // Class query messages are used by a management console to request a list of schema classes that are known by the management broker. - CLASS_INDICATION('q'), // Sent by the management broker, a class indication notifies the peer of the existence of a schema class. - SCHEMA_REQUEST('S'), // Schema request messages are used to request the full schema details for a class. - SCHEMA_RESPONSE('s'), // Schema response message contain a full description of the schema for a class. - HEARTBEAT_INDEICATION('h'), // This message is published once per publish-interval. It can be used by a client to positively determine which objects did not change during the interval (since updates are not published for objects with no changes). - CONFIG_INDICATION('c'), - INSTRUMENTATION_INDICATION('i'), - GET_QUERY_RESPONSE('g'), // This message contains a content record. Content records contain the values of all properties or statistics in an object. Such records are broadcast on a periodic interval if 1) a change has been made in the value of one of the elements, or 2) if a new management client has bound a queue to the management exchange. - GET_QUERY('G'), // Sent by a management console, a get query requests that the management broker provide content indications for all objects that match the query criteria. - METHOD_REQUEST('M'), // This message contains a method request. - METHOD_RESPONSE('m'), // This message contains a method result. - PACKAGE_QUERY('P'), // This message contains a schema package query request, requesting that the broker dump the list of known packages - PACKAGE_INDICATION('p'), // This message contains a schema package indication, identifying a package known by the broker - AGENT_ATTACH_REUQEST('A'), // This message is sent by a remote agent when it wishes to attach to a management broker - AGENT_ATTACH_RESPONSE('a'), // The management broker sends this response if an attaching remote agent is permitted to join - CONSOLE_ADDED_INDICATION('x'), // This message is sent to all remote agents by the management broker when a new console binds to the management exchange - EVENT('e') - ; - - - private final char _opcode; - - private static final QMFOperation[] OP_CODES = new QMFOperation[256]; - - - QMFOperation(char opcode) - { - _opcode = opcode; - } - - - public char getOpcode() - { - return _opcode; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java deleted file mode 100644 index 63b43475aa..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackage.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class QMFPackage -{ - private final String _name; - private final Map<String, QMFClass> _classes = new HashMap<String, QMFClass>(); - - public QMFPackage(String name) - { - _name = name; - } - - public QMFPackage(String name, Collection<QMFClass> classes) - { - this(name); - setClasses(classes); - } - - protected void setClasses(Collection<QMFClass> classes) - { - for(QMFClass qmfClass : classes) - { - qmfClass.setPackage(this); - _classes.put(qmfClass.getName(), qmfClass); - } - } - - public String getName() - { - return _name; - } - - public Collection<QMFClass> getClasses() - { - return _classes.values(); - } - - public QMFClass getQMFClass(String className) - { - return _classes.get(className); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java deleted file mode 100644 index c74c7da252..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageQueryCommand.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.Collection; -import java.util.List; - -public class QMFPackageQueryCommand extends QMFCommand -{ - - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - public QMFPackageQueryCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - Collection<QMFPackage> supportedSchemas = service.getSupportedSchemas(); - - QMFCommand[] commands = new QMFCommand[ supportedSchemas.size() + 1 ]; - - _qmfLogger.debug("Exectuting " + this); - - int i = 0; - for(QMFPackage p : supportedSchemas) - { - commands[i++] = new QMFPackageIndicationCommand(this, p.getName()); - } - commands[ commands.length - 1 ] = new QMFCommandCompletionCommand(this); - - - for(QMFCommand cmd : commands) - { - - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - public String toString() - { - return "QMFPackageQueryCommand"; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java deleted file mode 100644 index 5314466e2a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFProperty.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.Encoder; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class QMFProperty -{ - private final Map<String, Object> _map = new LinkedHashMap<String, Object>(); - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String ACCESS = "access"; - private static final String INDEX = "index"; - private static final String OPTIONAL = "optional"; - private static final String REF_PACKAGE = "refPackage"; - private static final String REF_CLASS = "refClass"; - private static final String UNIT = "unit"; - private static final String MIN = "min"; - private static final String MAX = "max"; - private static final String MAX_LENGTH = "maxlen"; - private static final String DESCRIPTION = "desc"; - - - public static enum AccessCode - { - RC, - RW, - RO; - - public int codeValue() - { - return ordinal()+1; - } - } - - public QMFProperty(String name, QMFType type, AccessCode accessCode, boolean index, boolean optional) - { - _map.put(NAME, name); - _map.put(TYPE, type.codeValue()); - _map.put(ACCESS, accessCode.codeValue()); - _map.put(INDEX, index ? 1 : 0); - _map.put(OPTIONAL, optional ? 1 :0); - } - - - public void setQMFClass(QMFClass qmfClass) - { - } - - public void setReferencedClass(String refClass) - { - _map.put(REF_CLASS, refClass); - } - - public void setReferencedPackage(String refPackage) - { - _map.put(REF_CLASS, refPackage); - } - - - public String getName() - { - return (String) _map.get(NAME); - } - - - public void setUnit(String unit) - { - _map.put(UNIT, unit); - } - - public void setMin(Number min) - { - _map.put(MIN, min); - } - - public void setMax(Number max) - { - _map.put(MAX, max); - } - - public void setMaxLength(int maxlen) - { - _map.put(MAX_LENGTH, maxlen); - } - - - public void setDescription(String description) - { - _map.put(DESCRIPTION, description); - } - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java deleted file mode 100644 index 57c67fa7f6..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaRequestCommand.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBDecoder; - -import java.util.List; - -public class QMFSchemaRequestCommand extends QMFCommand -{ - private static final Logger _qmfLogger = Logger.getLogger("qpid.qmf"); - - private final String _packageName; - private final String _className; - private final byte[] _hash; - - public QMFSchemaRequestCommand(QMFCommandHeader header, BBDecoder decoder) - { - super(header); - _packageName = decoder.readStr8(); - _className = decoder.readStr8(); - _hash = decoder.readBin128(); - } - - public void process(VirtualHost virtualHost, ServerMessage message) - { - _qmfLogger.debug("Execute: " + this); - - String exchangeName = message.getMessageHeader().getReplyToExchange(); - String routingKey = message.getMessageHeader().getReplyToRoutingKey(); - - IApplicationRegistry appRegistry = virtualHost.getApplicationRegistry(); - QMFService service = appRegistry.getQMFService(); - - QMFPackage qmfPackage = service.getPackage(_packageName); - QMFClass qmfClass = qmfPackage.getQMFClass( _className ); - - QMFCommand[] commands = new QMFCommand[2]; - commands[0] = new QMFSchemaResponseCommand(this, qmfClass); - commands[ 1 ] = new QMFCommandCompletionCommand(this); - - - - Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - - for(QMFCommand cmd : commands) - { - QMFMessage responseMessage = new QMFMessage(routingKey, cmd); - - - List<? extends BaseQueue> queues = exchange.route(responseMessage); - - for(BaseQueue q : queues) - { - try - { - q.enqueue(responseMessage); - } - catch (AMQException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - } - } - - @Override - public String toString() - { - return "QMFSchemaRequestCommand{" + - " packageName='" + _packageName + '\'' + - ", className='" + _className + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java deleted file mode 100644 index 4bd0e41989..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFSchemaResponseCommand.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.BBEncoder; - -import java.util.Collection; - -public class QMFSchemaResponseCommand extends QMFCommand -{ - private final QMFClass _qmfClass; - - - public QMFSchemaResponseCommand(QMFSchemaRequestCommand qmfSchemaRequestCommand, QMFClass qmfClass) - { - super(new QMFCommandHeader(qmfSchemaRequestCommand.getHeader().getVersion(), - qmfSchemaRequestCommand.getHeader().getSeq(), - QMFOperation.SCHEMA_RESPONSE)); - _qmfClass = qmfClass; - } - - @Override - public void encode(BBEncoder encoder) - { - super.encode(encoder); - encoder.writeUint8(_qmfClass.getType().getValue()); - encoder.writeStr8(_qmfClass.getPackage().getName()); - encoder.writeStr8(_qmfClass.getName()); - encoder.writeBin128(_qmfClass.getSchemaHash()); - - Collection<QMFProperty> props = _qmfClass.getProperties(); - Collection<QMFStatistic> stats = _qmfClass.getStatistics(); - Collection<QMFMethod> methods = _qmfClass.getMethods(); - - encoder.writeUint16(props.size()); - if(_qmfClass.getType() == QMFClass.Type.OBJECT) - { - encoder.writeUint16(stats.size()); - encoder.writeUint16(methods.size()); - } - - for(QMFProperty prop : props) - { - prop.encode(encoder); - } - - if(_qmfClass.getType() == QMFClass.Type.OBJECT) - { - - for(QMFStatistic stat : stats) - { - stat.encode(encoder); - } - - for(QMFMethod method : methods) - { - method.encode(encoder); - } - } - - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java deleted file mode 100644 index d713976919..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java +++ /dev/null @@ -1,2086 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.AMQException; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.qmf.schema.BrokerSchema; -import org.apache.qpid.server.configuration.*; -import org.apache.qpid.server.registry.IApplicationRegistry; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -public class QMFService implements ConfigStore.ConfigEventListener, Closeable -{ - - - private IApplicationRegistry _applicationRegistry; - private ConfigStore _configStore; - - - private final Map<String, QMFPackage> _supportedSchemas = new HashMap<String, QMFPackage>(); - private static final Map<String, ConfigObjectType> _qmfClassMapping = new HashMap<String, ConfigObjectType>(); - - static - { - _qmfClassMapping.put("system", SystemConfigType.getInstance()); - _qmfClassMapping.put("broker", BrokerConfigType.getInstance()); - _qmfClassMapping.put("vhost", VirtualHostConfigType.getInstance()); - _qmfClassMapping.put("exchange", ExchangeConfigType.getInstance()); - _qmfClassMapping.put("queue", QueueConfigType.getInstance()); - _qmfClassMapping.put("binding", BindingConfigType.getInstance()); - _qmfClassMapping.put("connection", ConnectionConfigType.getInstance()); - _qmfClassMapping.put("session", SessionConfigType.getInstance()); - _qmfClassMapping.put("subscription", SubscriptionConfigType.getInstance()); - _qmfClassMapping.put("link", LinkConfigType.getInstance()); - _qmfClassMapping.put("bridge", BridgeConfigType.getInstance()); - } - - private final Map<ConfigObjectType, ConfigObjectAdapter> _adapterMap = - new HashMap<ConfigObjectType, ConfigObjectAdapter>(); - private final Map<ConfigObjectType,QMFClass> _classMap = - new HashMap<ConfigObjectType,QMFClass>(); - - - private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>> _managedObjects = - new ConcurrentHashMap<QMFClass,ConcurrentHashMap<ConfiguredObject, QMFObject>>(); - - private final ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>> _managedObjectsById = - new ConcurrentHashMap<QMFClass,ConcurrentHashMap<UUID, QMFObject>>(); - - private static final BrokerSchema PACKAGE = BrokerSchema.getPackage(); - - public static interface Listener - { - public void objectCreated(QMFObject obj); - public void objectDeleted(QMFObject obj); - } - - private final CopyOnWriteArrayList<Listener> _listeners = new CopyOnWriteArrayList<Listener>(); - - abstract class ConfigObjectAdapter<Q extends QMFObject<S,D>, S extends QMFObjectClass<Q,D>, D extends QMFObject.Delegate, T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>> - { - private final T _type; - private final S _qmfClass; - - - protected ConfigObjectAdapter(final T type, final S qmfClass) - { - _type = type; - _qmfClass = qmfClass; - _adapterMap.put(type,this); - _classMap.put(type,qmfClass); - } - - public T getType() - { - return _type; - } - - public S getQMFClass() - { - return _qmfClass; - } - - protected final Q newInstance(D delegate) - { - return _qmfClass.newInstance(delegate); - } - - public abstract Q createQMFObject(C configObject); - } - - private ConfigObjectAdapter<BrokerSchema.SystemObject, - BrokerSchema.SystemClass, - BrokerSchema.SystemDelegate, - SystemConfigType, - SystemConfig> _systemObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.SystemObject, - BrokerSchema.SystemClass, - BrokerSchema.SystemDelegate, - SystemConfigType, - SystemConfig>(SystemConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.SystemClass.class)) - { - - - public BrokerSchema.SystemObject createQMFObject( - final SystemConfig configObject) - { - return newInstance(new SystemDelegate(configObject)); - } - }; - - private ConfigObjectAdapter<BrokerSchema.BrokerObject, - BrokerSchema.BrokerClass, - BrokerSchema.BrokerDelegate, - BrokerConfigType, - BrokerConfig> _brokerObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.BrokerObject, - BrokerSchema.BrokerClass, - BrokerSchema.BrokerDelegate, - BrokerConfigType, - BrokerConfig>(BrokerConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.BrokerClass.class)) - { - - public BrokerSchema.BrokerObject createQMFObject( - final BrokerConfig configObject) - { - return newInstance(new BrokerDelegate(configObject)); - } - }; - - private ConfigObjectAdapter<BrokerSchema.VhostObject, - BrokerSchema.VhostClass, - BrokerSchema.VhostDelegate, - VirtualHostConfigType, - VirtualHostConfig> _vhostObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.VhostObject, - BrokerSchema.VhostClass, - BrokerSchema.VhostDelegate, - VirtualHostConfigType, - VirtualHostConfig>(VirtualHostConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.VhostClass.class)) - { - - public BrokerSchema.VhostObject createQMFObject( - final VirtualHostConfig configObject) - { - return newInstance(new VhostDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.ExchangeObject, - BrokerSchema.ExchangeClass, - BrokerSchema.ExchangeDelegate, - ExchangeConfigType, - ExchangeConfig> _exchangeObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.ExchangeObject, - BrokerSchema.ExchangeClass, - BrokerSchema.ExchangeDelegate, - ExchangeConfigType, - ExchangeConfig>(ExchangeConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.ExchangeClass.class)) - { - - public BrokerSchema.ExchangeObject createQMFObject( - final ExchangeConfig configObject) - { - return newInstance(new ExchangeDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.QueueObject, - BrokerSchema.QueueClass, - BrokerSchema.QueueDelegate, - QueueConfigType, - QueueConfig> _queueObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.QueueObject, - BrokerSchema.QueueClass, - BrokerSchema.QueueDelegate, - QueueConfigType, - QueueConfig>(QueueConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.QueueClass.class)) - { - - public BrokerSchema.QueueObject createQMFObject( - final QueueConfig configObject) - { - return newInstance(new QueueDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.BindingObject, - BrokerSchema.BindingClass, - BrokerSchema.BindingDelegate, - BindingConfigType, - BindingConfig> _bindingObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.BindingObject, - BrokerSchema.BindingClass, - BrokerSchema.BindingDelegate, - BindingConfigType, - BindingConfig>(BindingConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.BindingClass.class)) - { - - public BrokerSchema.BindingObject createQMFObject( - final BindingConfig configObject) - { - return newInstance(new BindingDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.ConnectionObject, - BrokerSchema.ConnectionClass, - BrokerSchema.ConnectionDelegate, - ConnectionConfigType, - ConnectionConfig> _connectionObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.ConnectionObject, - BrokerSchema.ConnectionClass, - BrokerSchema.ConnectionDelegate, - ConnectionConfigType, - ConnectionConfig>(ConnectionConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.ConnectionClass.class)) - { - - public BrokerSchema.ConnectionObject createQMFObject( - final ConnectionConfig configObject) - { - return newInstance(new ConnectionDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.SessionObject, - BrokerSchema.SessionClass, - BrokerSchema.SessionDelegate, - SessionConfigType, - SessionConfig> _sessionObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.SessionObject, - BrokerSchema.SessionClass, - BrokerSchema.SessionDelegate, - SessionConfigType, - SessionConfig>(SessionConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.SessionClass.class)) - { - - public BrokerSchema.SessionObject createQMFObject( - final SessionConfig configObject) - { - return newInstance(new SessionDelegate(configObject)); - } - }; - - private ConfigObjectAdapter<BrokerSchema.SubscriptionObject, - BrokerSchema.SubscriptionClass, - BrokerSchema.SubscriptionDelegate, - SubscriptionConfigType, - SubscriptionConfig> _subscriptionObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.SubscriptionObject, - BrokerSchema.SubscriptionClass, - BrokerSchema.SubscriptionDelegate, - SubscriptionConfigType, - SubscriptionConfig>(SubscriptionConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.SubscriptionClass.class)) - { - - public BrokerSchema.SubscriptionObject createQMFObject( - final SubscriptionConfig configObject) - { - return newInstance(new SubscriptionDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.LinkObject, - BrokerSchema.LinkClass, - BrokerSchema.LinkDelegate, - LinkConfigType, - LinkConfig> _linkObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.LinkObject, - BrokerSchema.LinkClass, - BrokerSchema.LinkDelegate, - LinkConfigType, - LinkConfig>(LinkConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.LinkClass.class)) - { - - public BrokerSchema.LinkObject createQMFObject( - final LinkConfig configObject) - { - return newInstance(new LinkDelegate(configObject)); - } - }; - - - private ConfigObjectAdapter<BrokerSchema.BridgeObject, - BrokerSchema.BridgeClass, - BrokerSchema.BridgeDelegate, - BridgeConfigType, - BridgeConfig> _bridgeObjectAdapter = - new ConfigObjectAdapter<BrokerSchema.BridgeObject, - BrokerSchema.BridgeClass, - BrokerSchema.BridgeDelegate, - BridgeConfigType, - BridgeConfig>(BridgeConfigType.getInstance(), - PACKAGE.getQMFClassInstance(BrokerSchema.BridgeClass.class)) - { - - public BrokerSchema.BridgeObject createQMFObject( - final BridgeConfig configObject) - { - return newInstance(new BridgeDelegate(configObject)); - } - }; - - - - public QMFService(ConfigStore configStore, IApplicationRegistry applicationRegistry) - { - _configStore = configStore; - _applicationRegistry = applicationRegistry; - registerSchema(PACKAGE); - - for(ConfigObjectType v : _qmfClassMapping.values()) - { - configStore.addConfigEventListener(v, this); - } - init(); - } - - public void close() - { - for(ConfigObjectType v : _qmfClassMapping.values()) - { - _configStore.removeConfigEventListener(v, this); - } - _listeners.clear(); - - _managedObjects.clear(); - _managedObjectsById.clear(); - _classMap.clear(); - _adapterMap.clear(); - _supportedSchemas.clear(); - } - - - public void registerSchema(QMFPackage qmfPackage) - { - _supportedSchemas.put(qmfPackage.getName(), qmfPackage); - } - - - public Collection<QMFPackage> getSupportedSchemas() - { - return _supportedSchemas.values(); - } - - public QMFPackage getPackage(String aPackage) - { - return _supportedSchemas.get(aPackage); - } - - public void onEvent(final ConfiguredObject object, final ConfigStore.Event evt) - { - - switch (evt) - { - case CREATED: - manageObject(object); - break; - - case DELETED: - unmanageObject(object); - break; - } - } - - public QMFObject getObjectById(QMFClass qmfclass, UUID id) - { - ConcurrentHashMap<UUID, QMFObject> map = _managedObjectsById.get(qmfclass); - if(map != null) - { - - UUID key = new UUID(id.getMostSignificantBits() & (0xFFFl << 48), id.getLeastSignificantBits()); - return map.get(key); - - } - else - { - return null; - } - } - - private void unmanageObject(final ConfiguredObject object) - { - final QMFClass qmfClass = _classMap.get(object.getConfigType()); - - if(qmfClass == null) - { - return; - } - - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - if(classObjects != null) - { - QMFObject qmfObject = classObjects.remove(object); - if(qmfObject != null) - { - _managedObjectsById.get(qmfClass).remove(object.getQMFId()); - objectRemoved(qmfObject); - } - } - } - - private void manageObject(final ConfiguredObject object) - { - ConfigObjectAdapter adapter = _adapterMap.get(object.getConfigType()); - QMFObject qmfObject = adapter.createQMFObject(object); - final QMFClass qmfClass = qmfObject.getQMFClass(); - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - - if(classObjects == null) - { - classObjects = new ConcurrentHashMap<ConfiguredObject, QMFObject>(); - if(_managedObjects.putIfAbsent(qmfClass, classObjects) != null) - { - classObjects = _managedObjects.get(qmfClass); - } - } - - ConcurrentHashMap<UUID, QMFObject> classObjectsById = _managedObjectsById.get(qmfClass); - if(classObjectsById == null) - { - classObjectsById = new ConcurrentHashMap<UUID, QMFObject>(); - if(_managedObjectsById.putIfAbsent(qmfClass, classObjectsById) != null) - { - classObjectsById = _managedObjectsById.get(qmfClass); - } - } - - classObjectsById.put(object.getQMFId(),qmfObject); - - if(classObjects.putIfAbsent(object, qmfObject) == null) - { - objectAdded(qmfObject); - } - } - - private void objectRemoved(final QMFObject qmfObject) - { - qmfObject.setDeleteTime(); - for(Listener l : _listeners) - { - l.objectDeleted(qmfObject); - } - } - - private void objectAdded(final QMFObject qmfObject) - { - for(Listener l : _listeners) - { - l.objectCreated(qmfObject); - } - } - - public void addListener(Listener l) - { - _listeners.add(l); - } - - public void removeListener(Listener l) - { - _listeners.remove(l); - } - - - private void init() - { - for(QMFClass qmfClass : PACKAGE.getClasses()) - { - ConfigObjectType configType = getConfigType(qmfClass); - if(configType != null) - { - Collection<ConfiguredObject> objects = _configStore.getConfiguredObjects(configType); - for(ConfiguredObject object : objects) - { - manageObject(object); - } - } - } - } - - public Collection<QMFObject> getObjects(QMFClass qmfClass) - { - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - if(classObjects != null) - { - return classObjects.values(); - } - else - { - return Collections.EMPTY_SET; - } - } - - private QMFObject adapt(final ConfiguredObject object) - { - if(object == null) - { - return null; - } - - QMFClass qmfClass = _classMap.get(object.getConfigType()); - ConcurrentHashMap<ConfiguredObject, QMFObject> classObjects = _managedObjects.get(qmfClass); - if(classObjects != null) - { - QMFObject qmfObject = classObjects.get(object); - if(qmfObject != null) - { - return qmfObject; - } - } - - return _adapterMap.get(object.getConfigType()).createQMFObject(object); - } - - private ConfigObjectType getConfigType(final QMFClass qmfClass) - { - return _qmfClassMapping.get(qmfClass.getName()); - } - - private static class SystemDelegate implements BrokerSchema.SystemDelegate - { - private final SystemConfig _obj; - - public SystemDelegate(final SystemConfig obj) - { - _obj = obj; - } - - public UUID getSystemId() - { - return _obj.getQMFId(); - } - - public String getOsName() - { - return _obj.getOperatingSystemName(); - } - - public String getNodeName() - { - return _obj.getNodeName(); - } - - public String getRelease() - { - return _obj.getOSRelease(); - } - - public String getVersion() - { - return _obj.getOSVersion(); - } - - public String getMachine() - { - return _obj.getOSArchitecture(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class BrokerDelegate implements BrokerSchema.BrokerDelegate - { - private final BrokerConfig _obj; - - public BrokerDelegate(final BrokerConfig obj) - { - _obj = obj; - } - - public BrokerSchema.SystemObject getSystemRef() - { - return (BrokerSchema.SystemObject) adapt(_obj.getSystem()); - } - - public String getName() - { - return "amqp-broker"; - } - - public Integer getPort() - { - return _obj.getPort(); - } - - public Integer getWorkerThreads() - { - return _obj.getWorkerThreads(); - } - - public Integer getMaxConns() - { - return _obj.getMaxConnections(); - } - - public Integer getConnBacklog() - { - return _obj.getConnectionBacklogLimit(); - } - - public Long getStagingThreshold() - { - return _obj.getStagingThreshold(); - } - - public Boolean getMgmtPublish() - { - return true; - } - - public Integer getMgmtPubInterval() - { - return _obj.getManagementPublishInterval(); - } - - public String getVersion() - { - return _obj.getVersion(); - } - - public String getDataDir() - { - return _obj.getDataDirectory(); - } - - public Long getUptime() - { - return (System.currentTimeMillis() - _obj.getCreateTime()) * 1000000L; - } - - public Long getQueueCount() - { - // TODO - return 0L; - } - - public Long getMsgTotalEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgTotalDequeues() - { - // TODO - return 0L; - } - - public Long getByteTotalEnqueues() - { - // TODO - return 0L; - } - - public Long getByteTotalDequeues() - { - // TODO - return 0L; - } - - public Long getMsgDepth() - { - // TODO - return 0L; - } - - public Long getByteDepth() - { - // TODO - return 0L; - } - - public Long getMsgPersistEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgPersistDequeues() - { - // TODO - return 0L; - } - - public Long getBytePersistEnqueues() - { - // TODO - return 0L; - } - - public Long getBytePersistDequeues() - { - // TODO - return 0L; - } - - public Long getMsgTxnEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgTxnDequeues() - { - // TODO - return 0L; - } - - public Long getByteTxnEnqueues() - { - // TODO - return 0L; - } - - public Long getByteTxnDequeues() - { - // TODO - return 0L; - } - - public Long getMsgFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDequeues() - { - // TODO - return 0L; - } - - public Long getByteFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getByteFtdDequeues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDepth() - { - // TODO - return 0L; - } - - public Long getByteFtdDepth() - { - // TODO - return 0L; - } - - public Long getReleases() - { - // TODO - return 0L; - } - - public Long getAcquires() - { - // TODO - return 0L; - } - - public Long getDiscardsNoRoute() - { - // TODO - return 0L; - } - - public Long getDiscardsTtl() - { - // TODO - return 0L; - } - - public Long getDiscardsRing() - { - // TODO - return 0L; - } - - public Long getDiscardsLvq() - { - // TODO - return 0L; - } - - public Long getDiscardsOverflow() - { - // TODO - return 0L; - } - - public Long getDiscardsSubscriber() - { - // TODO - return 0L; - } - - public Long getDiscardsPurge() - { - // TODO - return 0L; - } - - public Long getReroutes() - { - // TODO - return 0L; - } - - public Long getAbandoned() - { - // TODO - return 0L; - } - - public Long getAbandonedViaAlt() - { - // TODO - return 0L; - } - - public BrokerSchema.BrokerClass.EchoMethodResponseCommand echo(final BrokerSchema.BrokerClass.EchoMethodResponseCommandFactory factory, - final Long sequence, - final String body) - { - return factory.createResponseCommand(sequence, body); - } - - public BrokerSchema.BrokerClass.ConnectMethodResponseCommand connect(final BrokerSchema.BrokerClass.ConnectMethodResponseCommandFactory factory, - final String host, - final Long port, - final Boolean durable, - final String authMechanism, - final String username, - final String password, - final String transport) - { - _obj.createBrokerConnection(transport, host, port.intValue(), durable, authMechanism, username, password); - - return factory.createResponseCommand(); - } - - public BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommand queueMoveMessages(final BrokerSchema.BrokerClass.QueueMoveMessagesMethodResponseCommandFactory factory, - final String srcQueue, - final String destQueue, - final Long qty, - final Map filter) // TODO: move based on group identifier - { - // TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.GetLogLevelMethodResponseCommand getLogLevel(final BrokerSchema.BrokerClass.GetLogLevelMethodResponseCommandFactory factory) - { - // TODO: The Java broker has numerous loggers, so we can't really implement this method properly. - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.SetLogLevelMethodResponseCommand setLogLevel(final BrokerSchema.BrokerClass.SetLogLevelMethodResponseCommandFactory factory, String level) - { - // TODO: The Java broker has numerous loggers, so we can't really implement this method properly. - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.GetTimestampConfigMethodResponseCommand getTimestampConfig(final BrokerSchema.BrokerClass.GetTimestampConfigMethodResponseCommandFactory factory) - { - // TODO: timestamp support - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.SetTimestampConfigMethodResponseCommand setTimestampConfig(final BrokerSchema.BrokerClass.SetTimestampConfigMethodResponseCommandFactory factory, - final java.lang.Boolean receive) - { - // TODO: timestamp support - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.CreateMethodResponseCommand create(final BrokerSchema.BrokerClass.CreateMethodResponseCommandFactory factory, - final String type, - final String name, - final Map properties, - final java.lang.Boolean lenient) - { - //TODO: - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.DeleteMethodResponseCommand delete(final BrokerSchema.BrokerClass.DeleteMethodResponseCommandFactory factory, - final String type, - final String name, - final Map options) - { - //TODO: - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.BrokerClass.QueryMethodResponseCommand query(final BrokerSchema.BrokerClass.QueryMethodResponseCommandFactory factory, - final String type, - final String name) - { - //TODO: - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class VhostDelegate implements BrokerSchema.VhostDelegate - { - private final VirtualHostConfig _obj; - - public VhostDelegate(final VirtualHostConfig obj) - { - _obj = obj; - } - - public BrokerSchema.BrokerObject getBrokerRef() - { - return (BrokerSchema.BrokerObject) adapt(_obj.getBroker()); - } - - public String getName() - { - return _obj.getName(); - } - - public String getFederationTag() - { - return _obj.getFederationTag(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class ExchangeDelegate implements BrokerSchema.ExchangeDelegate - { - private final ExchangeConfig _obj; - - public ExchangeDelegate(final ExchangeConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getName() - { - return _obj.getName(); - } - - public String getType() - { - return _obj.getType().getName().toString(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public Boolean getAutoDelete() - { - return _obj.isAutoDelete(); - } - - public BrokerSchema.ExchangeObject getAltExchange() - { - if(_obj.getAlternateExchange() != null) - { - return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange()); - } - else - { - return null; - } - } - - public Map getArguments() - { - return _obj.getArguments(); - } - - public Long getProducerCount() - { - // TODO - return 0l; - } - - public Long getProducerCountHigh() - { - // TODO - return 0l; - } - - public Long getProducerCountLow() - { - // TODO - return 0l; - } - - public Long getBindingCount() - { - return _obj.getBindingCount(); - } - - public Long getBindingCountHigh() - { - return _obj.getBindingCountHigh(); - } - - public Long getBindingCountLow() - { - // TODO - return 0l; - } - - public Long getMsgReceives() - { - return _obj.getMsgReceives(); - } - - public Long getMsgDrops() - { - return getMsgReceives() - getMsgRoutes(); - } - - public Long getMsgRoutes() - { - return _obj.getMsgRoutes(); - } - - public Long getByteReceives() - { - return _obj.getByteReceives(); - } - - public Long getByteDrops() - { - return getByteReceives() - getByteRoutes(); - } - - public Long getByteRoutes() - { - return _obj.getByteRoutes(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class QueueDelegate implements BrokerSchema.QueueDelegate - { - private final QueueConfig _obj; - - public QueueDelegate(final QueueConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getName() - { - return _obj.getName(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public Boolean getAutoDelete() - { - return _obj.isAutoDelete(); - } - - public Boolean getExclusive() - { - return _obj.isExclusive(); - } - - public BrokerSchema.ExchangeObject getAltExchange() - { - if(_obj.getAlternateExchange() != null) - { - return (BrokerSchema.ExchangeObject) adapt(_obj.getAlternateExchange()); - } - else - { - return null; - } - } - - public Long getMsgTotalEnqueues() - { - return _obj.getReceivedMessageCount(); - } - - public Long getMsgTotalDequeues() - { - return _obj.getMessageDequeueCount(); - } - - public Long getMsgTxnEnqueues() - { - return _obj.getMsgTxnEnqueues(); - } - - public Long getMsgTxnDequeues() - { - return _obj.getMsgTxnDequeues(); - } - - public Long getMsgPersistEnqueues() - { - return _obj.getPersistentMsgEnqueues(); - } - - public Long getMsgPersistDequeues() - { - return _obj.getPersistentMsgDequeues(); - } - - public Long getMsgDepth() - { - return (long) _obj.getMessageCount(); - } - - public Long getByteDepth() - { - return _obj.getQueueDepth(); - } - - public Long getByteTotalEnqueues() - { - return _obj.getTotalEnqueueSize(); - } - - public Long getByteTotalDequeues() - { - return _obj.getTotalDequeueSize(); - } - - public Long getByteTxnEnqueues() - { - return _obj.getByteTxnEnqueues(); - } - - public Long getByteTxnDequeues() - { - return _obj.getByteTxnDequeues(); - } - - public Long getBytePersistEnqueues() - { - return _obj.getPersistentByteEnqueues(); - } - - public Long getBytePersistDequeues() - { - return _obj.getPersistentByteDequeues(); - } - - public Long getMsgFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDequeues() - { - // TODO - return 0L; - } - - public Long getByteFtdEnqueues() - { - // TODO - return 0L; - } - - public Long getByteFtdDequeues() - { - // TODO - return 0L; - } - - public Long getMsgFtdDepth() - { - // TODO - return 0L; - } - - public Long getByteFtdDepth() - { - // TODO - return 0L; - } - - public Long getReleases() - { - // TODO - return 0L; - } - - public Long getAcquires() - { - // TODO - return 0L; - } - - public Long getDiscardsTtl() - { - // TODO - return 0L; - } - - public Long getDiscardsRing() - { - // TODO - return 0L; - } - - public Long getDiscardsLvq() - { - // TODO - return 0L; - } - - public Long getDiscardsOverflow() - { - // TODO - return 0L; - } - - public Long getDiscardsSubscriber() - { - // TODO - return 0L; - } - - public Long getDiscardsPurge() - { - // TODO - return 0L; - } - - public Long getReroutes() - { - // TODO - return 0L; - } - - public Long getConsumerCount() - { - return (long) _obj.getConsumerCount(); - } - - public Long getConsumerCountHigh() - { - return (long) _obj.getConsumerCountHigh(); - } - - public Long getConsumerCountLow() - { - // TODO - return 0l; - } - - public Long getBindingCount() - { - return (long) _obj.getBindingCount(); - } - - public Long getBindingCountHigh() - { - return (long) _obj.getBindingCountHigh(); - } - - public Long getBindingCountLow() - { - // TODO - return 0l; - } - - public Long getUnackedMessages() - { - return _obj.getUnackedMessageCount(); - } - - public Long getUnackedMessagesHigh() - { - return _obj.getUnackedMessageCountHigh(); - } - - public Long getUnackedMessagesLow() - { - // TODO - return 0l; - } - - public Long getMessageLatencySamples() - { - // TODO - return 0l; - } - - public Long getMessageLatencyMin() - { - // TODO - return 0l; - } - - public Long getMessageLatencyMax() - { - // TODO - return 0l; - } - - public Long getMessageLatencyAverage() - { - // TODO - return 0l; - } - - public Boolean getFlowStopped() - { - return Boolean.FALSE; - } - - public Long getFlowStoppedCount() - { - return 0L; - } - - public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory, - final Long request, - final Map filter) // TODO: support for purge-by-group-identifier - { - try - { - _obj.purge(request); - } catch (AMQException e) - { - // TODO - throw new RuntimeException(); - } - return factory.createResponseCommand(); - } - - public BrokerSchema.QueueClass.RerouteMethodResponseCommand reroute(final BrokerSchema.QueueClass.RerouteMethodResponseCommandFactory factory, - final Long request, - final Boolean useAltExchange, - final String exchange, - final Map filter) // TODO: support for re-route-by-group-identifier - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - - public Map getArguments() - { - return _obj.getArguments(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class BindingDelegate implements BrokerSchema.BindingDelegate - { - private final BindingConfig _obj; - - public BindingDelegate(final BindingConfig obj) - { - _obj = obj; - } - - public BrokerSchema.ExchangeObject getExchangeRef() - { - return (BrokerSchema.ExchangeObject) adapt(_obj.getExchange()); - } - - public BrokerSchema.QueueObject getQueueRef() - { - return (BrokerSchema.QueueObject) adapt(_obj.getQueue()); - } - - public String getBindingKey() - { - return _obj.getBindingKey(); - } - - public Map getArguments() - { - return _obj.getArguments(); - } - - public String getOrigin() - { - return _obj.getOrigin(); - } - - public Long getMsgMatched() - { - // TODO - return _obj.getMatches(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class ConnectionDelegate implements BrokerSchema.ConnectionDelegate - { - private final ConnectionConfig _obj; - - public ConnectionDelegate(final ConnectionConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getAddress() - { - return _obj.getAddress(); - } - - public Boolean getIncoming() - { - return _obj.isIncoming(); - } - - public Boolean getSystemConnection() - { - return _obj.isSystemConnection(); - } - - public Boolean getFederationLink() - { - return _obj.isFederationLink(); - } - - public String getAuthIdentity() - { - return _obj.getAuthId(); - } - - public String getRemoteProcessName() - { - return _obj.getRemoteProcessName(); - } - - public Long getRemotePid() - { - Integer remotePID = _obj.getRemotePID(); - return remotePID == null ? null : (long) remotePID; - } - - public Long getRemoteParentPid() - { - Integer remotePPID = _obj.getRemoteParentPID(); - return remotePPID == null ? null : (long) remotePPID; - - } - - public Boolean getClosing() - { - return false; - } - - public Long getFramesFromClient() - { - // TODO - return 0l; - } - - public Long getFramesToClient() - { - // TODO - return 0l; - } - - public Long getBytesFromClient() - { - // TODO - return 0l; - } - - public Long getBytesToClient() - { - // TODO - return 0l; - } - - public Long getMsgsFromClient() - { - // TODO - return 0l; - } - - public Long getMsgsToClient() - { - // TODO - return 0l; - } - - public BrokerSchema.ConnectionClass.CloseMethodResponseCommand close(final BrokerSchema.ConnectionClass.CloseMethodResponseCommandFactory factory) - { - _obj.mgmtClose(); - - return factory.createResponseCommand(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public Boolean getShadow() - { - return _obj.isShadow(); - } - - public Boolean getUserProxyAuth() - { - // TODO - return false; - } - - public String getSaslMechanism() - { - // TODO - return null; - } - public Integer getSaslSsf() - { - // TODO - return 0; - } - - - public String toString() - { - return _obj.toString(); - } - } - - private class SessionDelegate implements BrokerSchema.SessionDelegate - { - private final SessionConfig _obj; - - public SessionDelegate(final SessionConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getName() - { - return _obj.getSessionName(); - } - - public Integer getChannelId() - { - return _obj.getChannel(); - } - - public BrokerSchema.ConnectionObject getConnectionRef() - { - return (BrokerSchema.ConnectionObject) adapt(_obj.getConnectionConfig()); - } - - public Long getDetachedLifespan() - { - return _obj.getDetachedLifespan(); - } - - public Boolean getAttached() - { - return _obj.isAttached(); - } - - public Long getExpireTime() - { - return _obj.getExpiryTime(); - } - - public Long getMaxClientRate() - { - return _obj.getMaxClientRate(); - } - - public Long getFramesOutstanding() - { - // TODO - return 0l; - } - - public Long getUnackedMessages() - { - // TODO - return 0l; - } - - public Long getTxnStarts() - { - return _obj.getTxnStarts(); - } - - public Long getTxnCommits() - { - return _obj.getTxnCommits(); - } - - public Long getTxnRejects() - { - return _obj.getTxnRejects(); - } - - public Long getTxnCount() - { - return _obj.getTxnCount(); - } - - public Long getClientCredit() - { - // TODO - return 0l; - } - - public BrokerSchema.SessionClass.SolicitAckMethodResponseCommand solicitAck(final BrokerSchema.SessionClass.SolicitAckMethodResponseCommandFactory factory) - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.SessionClass.DetachMethodResponseCommand detach(final BrokerSchema.SessionClass.DetachMethodResponseCommandFactory factory) - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.SessionClass.ResetLifespanMethodResponseCommand resetLifespan(final BrokerSchema.SessionClass.ResetLifespanMethodResponseCommandFactory factory) - { - //TODO - return factory.createResponseCommand(CompletionCode.NOT_IMPLEMENTED); - } - - public BrokerSchema.SessionClass.CloseMethodResponseCommand close(final BrokerSchema.SessionClass.CloseMethodResponseCommandFactory factory) - { - try - { - _obj.mgmtClose(); - } - catch (AMQException e) - { - return factory.createResponseCommand(CompletionCode.EXCEPTION, e.getMessage()); - } - - return factory.createResponseCommand(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class SubscriptionDelegate implements BrokerSchema.SubscriptionDelegate - { - private final SubscriptionConfig _obj; - - private SubscriptionDelegate(final SubscriptionConfig obj) - { - _obj = obj; - } - - - public BrokerSchema.SessionObject getSessionRef() - { - return (BrokerSchema.SessionObject) adapt(_obj.getSessionConfig()); - } - - public BrokerSchema.QueueObject getQueueRef() - { - return (BrokerSchema.QueueObject) adapt(_obj.getQueue()); - } - - public String getName() - { - return _obj.getName(); - } - - public Boolean getBrowsing() - { - return _obj.isBrowsing(); - } - - public Boolean getAcknowledged() - { - return _obj.isExplicitAcknowledge(); - } - - public Boolean getExclusive() - { - return _obj.isExclusive(); - } - - public String getCreditMode() - { - return _obj.getCreditMode(); - } - - public Map getArguments() - { - return _obj.getArguments(); - } - - public Long getDelivered() - { - return _obj.getDelivered(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class BridgeDelegate implements BrokerSchema.BridgeDelegate - { - private final BridgeConfig _obj; - - private BridgeDelegate(final BridgeConfig obj) - { - _obj = obj; - } - - public BrokerSchema.LinkObject getLinkRef() - { - return (BrokerSchema.LinkObject) adapt(_obj.getLink()); - } - - public Integer getChannelId() - { - return _obj.getChannelId(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public String getSrc() - { - return _obj.getSource(); - } - - public String getDest() - { - return _obj.getDestination(); - } - - public String getKey() - { - return _obj.getKey(); - } - - public Boolean getSrcIsQueue() - { - return _obj.isQueueBridge(); - } - - public Boolean getSrcIsLocal() - { - return _obj.isLocalSource(); - } - - public String getTag() - { - return _obj.getTag(); - } - - public String getExcludes() - { - return _obj.getExcludes(); - } - - public Boolean getDynamic() - { - return _obj.isDynamic(); - } - - public Integer getSync() - { - return _obj.getAckBatching(); - } - - /* support TBD */ - public String getName() - { - return null; - } - - public BrokerSchema.BridgeClass.CloseMethodResponseCommand close(final BrokerSchema.BridgeClass.CloseMethodResponseCommandFactory factory) - { - return null; - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - public String toString() - { - return _obj.toString(); - } - } - - private class LinkDelegate implements BrokerSchema.LinkDelegate - { - private final LinkConfig _obj; - - private LinkDelegate(final LinkConfig obj) - { - _obj = obj; - } - - public BrokerSchema.VhostObject getVhostRef() - { - return (BrokerSchema.VhostObject) adapt(_obj.getVirtualHost()); - } - - public String getHost() - { - return _obj.getHost(); - } - - public Integer getPort() - { - return _obj.getPort(); - } - - public String getTransport() - { - return _obj.getTransport(); - } - - public Boolean getDurable() - { - return _obj.isDurable(); - } - - public String getState() - { - return _obj.getState(); - } - - public String getLastError() - { - return _obj.getLastError(); - } - - /* support TBD */ - public String getName() - { - return null; - } - - /* support TBD */ - public BrokerSchema.ConnectionObject getConnectionRef() - { - return (BrokerSchema.ConnectionObject) null; - } - - public BrokerSchema.LinkClass.CloseMethodResponseCommand close(final BrokerSchema.LinkClass.CloseMethodResponseCommandFactory factory) - { - _obj.close(); - return factory.createResponseCommand(); - } - - public BrokerSchema.LinkClass.BridgeMethodResponseCommand bridge(final BrokerSchema.LinkClass.BridgeMethodResponseCommandFactory factory, - final Boolean durable, - final String src, - final String dest, - final String key, - final String tag, - final String excludes, - final Boolean srcIsQueue, - final Boolean srcIsLocal, - final Boolean dynamic, - final Integer sync) - { - _obj.createBridge(durable, dynamic, srcIsQueue, srcIsLocal, src, dest, key, tag, excludes); - return factory.createResponseCommand(); - } - - public UUID getQMFId() - { - return _obj.getQMFId(); - } - - public long getCreateTime() - { - return _obj.getCreateTime(); - } - - @Override - public String toString() - { - return _obj.toString(); - } - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java deleted file mode 100644 index 89d650e03b..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFStatistic.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.qmf; - -import org.apache.qpid.transport.codec.Encoder; - -import java.util.LinkedHashMap; - -public class QMFStatistic -{ - private final LinkedHashMap<String,Object> _map = new LinkedHashMap<String,Object>(); - private static final String NAME = "name"; - private static final String TYPE = "type"; - private static final String UNIT = "unit"; - private static final String DESCRIPTION = "desc"; - - - public QMFStatistic(String name, QMFType type, String unit, String description) - { - _map.put(NAME, name); - _map.put(TYPE, type.codeValue()); - if(unit != null) - { - _map.put(UNIT, unit); - } - if(description != null) - { - _map.put(DESCRIPTION, description); - } - - } - - public void encode(Encoder encoder) - { - encoder.writeMap(_map); - } - - public String getName() - { - return (String) _map.get(NAME); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index e197dddfde..ab4ca81d05 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -51,13 +51,10 @@ import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction; import org.apache.qpid.server.ack.UnacknowledgedMessageMap; import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SessionConfigType; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.flow.FlowCreditManager; import org.apache.qpid.server.flow.Pre0_10CreditManager; @@ -75,7 +72,6 @@ import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.protocol.AMQConnectionModel; -import org.apache.qpid.server.protocol.AMQProtocolEngine; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; @@ -83,7 +79,6 @@ import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.InboundMessageAdapter; import org.apache.qpid.server.queue.IncomingMessage; import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreFuture; import org.apache.qpid.server.store.StoredMessage; @@ -93,19 +88,19 @@ import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; import org.apache.qpid.server.txn.AsyncAutoCommitTransaction; import org.apache.qpid.server.txn.LocalTransaction; +import org.apache.qpid.server.txn.LocalTransaction.ActivityTimeAccessor; import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.TransportException; -public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder +public class AMQChannel implements AMQSessionModel, AsyncAutoCommitTransaction.FutureRecorder { public static final int DEFAULT_PREFETCH = 4096; private static final Logger _logger = Logger.getLogger(AMQChannel.class); - private static final boolean MSG_AUTH = - ApplicationRegistry.getInstance().getConfiguration().getMsgAuth(); - + //TODO use Broker property to configure message authorization requirements + private boolean _messageAuthorizationRequired = Boolean.getBoolean(BrokerProperties.PROPERTY_MSG_AUTH); private final int _channelId; @@ -118,7 +113,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm */ private long _deliveryTag = 0; - /** A channel has a default queue (the last declared) that is used when no queue name is explictily set */ + /** A channel has a default queue (the last declared) that is used when no queue name is explicitly set */ private AMQQueue _defaultQueue; /** This tag is unique per subscription to a queue. The server returns this in response to a basic.consume request. */ @@ -151,7 +146,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm private final AtomicLong _txnCommits = new AtomicLong(0); private final AtomicLong _txnRejects = new AtomicLong(0); private final AtomicLong _txnCount = new AtomicLong(0); - private final AtomicLong _txnUpdateTime = new AtomicLong(0); private final AMQProtocolSession _session; private AtomicBoolean _closing = new AtomicBoolean(false); @@ -169,12 +163,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm private List<QueueEntry> _resendList = new ArrayList<QueueEntry>(); private static final AMQShortString IMMEDIATE_DELIVERY_REPLY_TEXT = new AMQShortString("Immediate delivery is not possible."); - private final UUID _qmfId; private long _createTime = System.currentTimeMillis(); private final ClientDeliveryMethod _clientDeliveryMethod; private final TransactionTimeoutHelper _transactionTimeoutHelper; + private final UUID _id = UUID.randomUUID(); public AMQChannel(AMQProtocolSession session, int channelId, MessageStore messageStore) throws AMQException @@ -184,30 +178,36 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm _actor = new AMQPChannelActor(this, session.getLogActor().getRootMessageLogger()); _logSubject = new ChannelLogSubject(this); - _qmfId = getConfigStore().createId(); _actor.message(ChannelMessages.CREATE()); - getConfigStore().addConfiguredObject(this); - _messageStore = messageStore; // by default the session is non-transactional _transaction = new AsyncAutoCommitTransaction(_messageStore, this); - _clientDeliveryMethod = session.createDeliveryMethod(_channelId); - - _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject); - } + _clientDeliveryMethod = session.createDeliveryMethod(_channelId); - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); + _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, new CloseAction() + { + @Override + public void doTimeoutAction(String reason) throws AMQException + { + closeConnection(reason); + } + }); } /** Sets this channel to be part of a local transaction */ public void setLocalTransactional() { - _transaction = new LocalTransaction(_messageStore); + _transaction = new LocalTransaction(_messageStore, new ActivityTimeAccessor() + { + @Override + public long getActivityTime() + { + return _session.getLastReceivedTime(); + } + }); _txnStarts.incrementAndGet(); } @@ -221,12 +221,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm sync(); } - - public boolean inTransaction() - { - return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0; - } - private void incrementOutstandingTxnsIfNecessary() { if(isTransactional()) @@ -247,11 +241,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } - public Long getTxnStarts() - { - return _txnStarts.get(); - } - public Long getTxnCommits() { return _txnCommits.get(); @@ -369,9 +358,8 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } }); - _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues), getProtocolSession().getLastReceivedTime()); + _transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues)); incrementOutstandingTxnsIfNecessary(); - updateTransactionalActivity(); _currentMessage.getStoredMessage().flushToStore(); } } @@ -396,7 +384,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm if (_logger.isDebugEnabled()) { - _logger.debug(debugIdentity() + "Content body received on channel " + _channelId); + _logger.debug(debugIdentity() + " content body received on channel " + _channelId); } try @@ -556,9 +544,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm { _logger.error("Caught TransportException whilst attempting to requeue:" + e); } - - getConfigStore().removeConfiguredObject(this); - } private void unsubscribeAllConsumers() throws AMQException @@ -860,7 +845,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm { Collection<QueueEntry> ackedMessages = getAckedMessages(deliveryTag, multiple); _transaction.dequeue(ackedMessages, new MessageAcknowledgeAction(ackedMessages)); - updateTransactionalActivity(); } private Collection<QueueEntry> getAckedMessages(long deliveryTag, boolean multiple) @@ -1054,19 +1038,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm } } - - - } - - /** - * Update last transaction activity timestamp - */ - private void updateTransactionalActivity() - { - if (isTransactional()) - { - _txnUpdateTime.set(getProtocolSession().getLastReceivedTime()); - } } public String toString() @@ -1149,10 +1120,16 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm ? ((BasicContentHeaderProperties) header.getProperties()).getUserId() : null; - return (!MSG_AUTH || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString())); + return (!_messageAuthorizationRequired || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString())); } + @Override + public UUID getId() + { + return _id; + } + public AMQConnectionModel getConnectionModel() { return _session; @@ -1168,6 +1145,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm return _logSubject; } + @Override + public int compareTo(AMQSessionModel o) + { + return getId().compareTo(o.getId()); + } + private class MessageDeliveryAction implements ServerTransaction.Action { private IncomingMessage _incommingMessage; @@ -1221,11 +1204,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm // TODO throw new RuntimeException(e); } - - - - - } public void onRollback() @@ -1375,7 +1353,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm public void onRollback() { - //To change body of implemented methods use File | Settings | File Templates. } } @@ -1469,97 +1446,24 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm return getProtocolSession().getVirtualHost(); } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - - public SessionConfigType getConfigType() - { - return SessionConfigType.getInstance(); - } - public int getChannel() { return getChannelId(); } - public boolean isAttached() - { - return true; - } - - public long getDetachedLifespan() - { - return 0; - } - - public ConnectionConfig getConnectionConfig() - { - return (AMQProtocolEngine)getProtocolSession(); - } - - public Long getExpiryTime() - { - return null; - } - - public Long getMaxClientRate() - { - return null; - } - public boolean isDurable() { return false; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public String getSessionName() - { - return getConnectionConfig().getAddress() + "/" + getChannelId(); - } - public long getCreateTime() { return _createTime; } - public void mgmtClose() throws AMQException - { - _session.mgmtCloseChannel(_channelId); - } - public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException { - if (inTransaction()) - { - long currentTime = System.currentTimeMillis(); - long openTime = currentTime - _transaction.getTransactionStartTime(); - long idleTime = currentTime - _txnUpdateTime.get(); - - _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime), - TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose)) - { - closeConnection("Idle transaction timed out"); - return; - } - - _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime), - TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(openTime, openClose)) - { - closeConnection("Open transaction timed out"); - return; - } - } + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, openWarn, openClose, idleWarn, idleClose); } /** @@ -1637,6 +1541,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm public void sync() { + if(_logger.isDebugEnabled()) + { + _logger.debug("sync() called on channel " + debugIdentity()); + } + AsyncCommand cmd; while((cmd = _unfinishedCommandsQueue.poll()) != null) { @@ -1674,16 +1583,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel, AsyncAutoComm _action.postCommit(); _action = null; } - - boolean isReadyForCompletion() - { - return _future.isComplete(); - } - } - - public int compareTo(AMQSessionModel session) - { - return getQMFId().compareTo(session.getQMFId()); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/java/broker/src/main/java/org/apache/qpid/server/Broker.java index d58a0d5bb4..54dcf0543d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Broker.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Broker.java @@ -23,37 +23,31 @@ package org.apache.qpid.server; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.*; -import javax.net.ssl.SSLContext; +import java.util.List; +import java.util.Properties; +import java.util.Set; + import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.BrokerConfigurationStoreCreator; +import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler; import org.apache.qpid.server.logging.SystemOutMessageLogger; import org.apache.qpid.server.logging.actors.BrokerActor; import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.logging.actors.GenericActor; -import org.apache.qpid.server.logging.log4j.LoggingFacade; +import org.apache.qpid.server.logging.log4j.LoggingManagementFacade; import org.apache.qpid.server.logging.messages.BrokerMessages; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory; import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry; -import org.apache.qpid.server.transport.QpidAcceptor; -import org.apache.qpid.ssl.SSLContextFactory; -import org.apache.qpid.transport.NetworkTransportConfiguration; -import org.apache.qpid.transport.network.IncomingNetworkTransport; -import org.apache.qpid.transport.network.Transport; - -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; +import org.apache.qpid.server.registry.IApplicationRegistry; public class Broker { private static final Logger LOGGER = Logger.getLogger(Broker.class); private volatile Thread _shutdownHookThread; + private volatile IApplicationRegistry _applicationRegistry; protected static class InitException extends RuntimeException { @@ -73,7 +67,17 @@ public class Broker } finally { - ApplicationRegistry.remove(); + try + { + if (_applicationRegistry != null) + { + _applicationRegistry.close(); + } + } + finally + { + clearAMQShortStringCache(); + } } } @@ -84,274 +88,76 @@ public class Broker public void startup(final BrokerOptions options) throws Exception { + CurrentActor.set(new BrokerActor(new SystemOutMessageLogger())); try { - CurrentActor.set(new BrokerActor(new SystemOutMessageLogger())); startupImpl(options); addShutdownHook(); } finally { - CurrentActor.remove(); + try + { + CurrentActor.remove(); + } + finally + { + clearAMQShortStringCache(); + } } } private void startupImpl(final BrokerOptions options) throws Exception { - final String qpidHome = options.getQpidHome(); - final File configFile = getConfigFile(options.getConfigFile(), - BrokerOptions.DEFAULT_CONFIG_FILE, qpidHome, true); - - CurrentActor.get().message(BrokerMessages.CONFIG(configFile.getAbsolutePath())); - - File logConfigFile = getConfigFile(options.getLogConfigFile(), - BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false); - - configureLogging(logConfigFile, options.getLogWatchFrequency()); + final String qpidHome = System.getProperty(BrokerProperties.PROPERTY_QPID_HOME); + String storeLocation = options.getConfigurationStoreLocation(); + String storeType = options.getConfigurationStoreType(); - ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile, options.getBundleContext()); - ServerConfiguration serverConfig = config.getConfiguration(); - if (options.getQpidWork() != null) + if (storeLocation == null) { - serverConfig.setQpidWork(options.getQpidWork()); - } - if (options.getQpidHome() != null) - { - serverConfig.setQpidHome(options.getQpidHome()); - } - updateManagementPorts(serverConfig, options.getJmxPortRegistryServer(), options.getJmxPortConnectorServer()); - - ApplicationRegistry.initialise(config); - - // We have already loaded the BrokerMessages class by this point so we - // need to refresh the locale setting incase we had a different value in - // the configuration. - BrokerMessages.reload(); - - // AR.initialise() sets and removes its own actor so we now need to set the actor - // for the remainder of the startup, and the default actor if the stack is empty - CurrentActor.set(new BrokerActor(config.getCompositeStartupMessageLogger())); - CurrentActor.setDefault(new BrokerActor(config.getRootMessageLogger())); - GenericActor.setDefaultMessageLogger(config.getRootMessageLogger()); - - try - { - Set<Integer> ports = new HashSet<Integer>(options.getPorts()); - if(ports.isEmpty()) - { - parsePortList(ports, serverConfig.getPorts()); - } - - Set<Integer> sslPorts = new HashSet<Integer>(options.getSSLPorts()); - if(sslPorts.isEmpty()) - { - parsePortList(sslPorts, serverConfig.getSSLPorts()); - } - - //1-0 excludes and includes - Set<Integer> exclude_1_0 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v1_0)); - if(exclude_1_0.isEmpty()) - { - parsePortList(exclude_1_0, serverConfig.getPortExclude10()); - } - - Set<Integer> include_1_0 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v1_0)); - if(include_1_0.isEmpty()) - { - parsePortList(include_1_0, serverConfig.getPortInclude10()); - } - - //0-10 excludes and includes - Set<Integer> exclude_0_10 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_10)); - if(exclude_0_10.isEmpty()) - { - parsePortList(exclude_0_10, serverConfig.getPortExclude010()); - } - - Set<Integer> include_0_10 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_10)); - if(include_0_10.isEmpty()) - { - parsePortList(include_0_10, serverConfig.getPortInclude010()); - } - - //0-9-1 excludes and includes - Set<Integer> exclude_0_9_1 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9_1)); - if(exclude_0_9_1.isEmpty()) - { - parsePortList(exclude_0_9_1, serverConfig.getPortExclude091()); - } - - Set<Integer> include_0_9_1 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_9_1)); - if(include_0_9_1.isEmpty()) - { - parsePortList(include_0_9_1, serverConfig.getPortInclude091()); - } - - //0-9 excludes and includes - Set<Integer> exclude_0_9 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9)); - if(exclude_0_9.isEmpty()) - { - parsePortList(exclude_0_9, serverConfig.getPortExclude09()); - } - - Set<Integer> include_0_9 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_9)); - if(include_0_9.isEmpty()) - { - parsePortList(include_0_9, serverConfig.getPortInclude09()); - } - - //0-8 excludes and includes - Set<Integer> exclude_0_8 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_8)); - if(exclude_0_8.isEmpty()) - { - parsePortList(exclude_0_8, serverConfig.getPortExclude08()); - } - - Set<Integer> include_0_8 = new HashSet<Integer>(options.getIncludedPorts(ProtocolInclusion.v0_8)); - if(include_0_8.isEmpty()) - { - parsePortList(include_0_8, serverConfig.getPortInclude08()); - } - - String bindAddr = options.getBind(); - if (bindAddr == null) - { - bindAddr = serverConfig.getBind(); - } - - InetAddress bindAddress; - if (bindAddr.equals(WILDCARD_ADDRESS)) - { - bindAddress = null; - } - else - { - bindAddress = InetAddress.getByName(bindAddr); - } - - final AmqpProtocolVersion defaultSupportedProtocolReply = serverConfig.getDefaultSupportedProtocolReply(); - - if (!serverConfig.getSSLOnly()) - { - for(int port : ports) - { - final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, port); - - final Set<AmqpProtocolVersion> supported = - getSupportedVersions(port, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, - include_1_0, include_0_10, include_0_9_1, include_0_9, include_0_8,serverConfig); - - final NetworkTransportConfiguration settings = - new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); - - final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance(); - final MultiVersionProtocolEngineFactory protocolEngineFactory = - new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply); - - transport.accept(settings, protocolEngineFactory, null); - - ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress, - new QpidAcceptor(transport,QpidAcceptor.Transport.TCP, supported)); - CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port)); - } - } - - if (serverConfig.getEnableSSL()) + String qpidWork = System.getProperty(BrokerProperties.PROPERTY_QPID_WORK); + if (qpidWork == null) { - final String keystorePath = serverConfig.getConnectorKeyStorePath(); - final String keystorePassword = serverConfig.getConnectorKeyStorePassword(); - final String keystoreType = serverConfig.getConnectorKeyStoreType(); - final String keyManagerFactoryAlgorithm = serverConfig.getConnectorKeyManagerFactoryAlgorithm(); - final SSLContext sslContext; - if(serverConfig.getConnectorTrustStorePath()!=null) - { - sslContext = SSLContextFactory.buildClientContext(serverConfig.getConnectorTrustStorePath(), - serverConfig.getConnectorTrustStorePassword(), - serverConfig.getConnectorTrustStoreType(), - serverConfig.getConnectorTrustManagerFactoryAlgorithm(), - keystorePath, - keystorePassword, keystoreType, keyManagerFactoryAlgorithm, - serverConfig.getCertAlias()); - } - else - { - sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm); - } - - for(int sslPort : sslPorts) - { - final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, sslPort); - - final Set<AmqpProtocolVersion> supported = - getSupportedVersions(sslPort, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, - include_1_0, include_0_10, include_0_9_1, include_0_9, include_0_8, serverConfig); - final NetworkTransportConfiguration settings = - new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); - - final IncomingNetworkTransport transport = Transport.getIncomingTransportInstance(); - final MultiVersionProtocolEngineFactory protocolEngineFactory = - new MultiVersionProtocolEngineFactory(supported, defaultSupportedProtocolReply); - - transport.accept(settings, protocolEngineFactory, sslContext); - - ApplicationRegistry.getInstance().addAcceptor(inetSocketAddress, - new QpidAcceptor(transport,QpidAcceptor.Transport.SSL, supported)); - CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort)); - } + qpidWork = new File(System.getProperty("user.dir"), "work").getAbsolutePath(); } - - CurrentActor.get().message(BrokerMessages.READY()); - } - finally - { - // Startup is complete so remove the AR initialised Startup actor - CurrentActor.remove(); + storeLocation = new File(qpidWork, BrokerOptions.DEFAULT_CONFIG_FILE + "." + storeType).getAbsolutePath(); } - } - private static Set<AmqpProtocolVersion> getSupportedVersions(final int port, - final Set<Integer> exclude_1_0, - final Set<Integer> exclude_0_10, - final Set<Integer> exclude_0_9_1, - final Set<Integer> exclude_0_9, - final Set<Integer> exclude_0_8, - final Set<Integer> include_1_0, - final Set<Integer> include_0_10, - final Set<Integer> include_0_9_1, - final Set<Integer> include_0_9, - final Set<Integer> include_0_8, - final ServerConfiguration serverConfig) - { - final EnumSet<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class); + CurrentActor.get().message(BrokerMessages.CONFIG(storeLocation)); - if((exclude_1_0.contains(port) || !serverConfig.isAmqp10enabled()) && !include_1_0.contains(port)) - { - supported.remove(AmqpProtocolVersion.v1_0_0); - } + File logConfigFile = getConfigFile(options.getLogConfigFile(), BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false); + configureLogging(logConfigFile, options.getLogWatchFrequency()); - if((exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled()) && !include_0_10.contains(port)) - { - supported.remove(AmqpProtocolVersion.v0_10); - } + BrokerConfigurationStoreCreator storeCreator = new BrokerConfigurationStoreCreator(); + ConfigurationEntryStore store = storeCreator.createStore(storeLocation, storeType, + options.getInitialConfigurationStoreLocation(), options.getInitialConfigurationStoreLocation()); - if((exclude_0_9_1.contains(port) || !serverConfig.isAmqp091enabled()) && !include_0_9_1.contains(port)) + if (options.isManagementMode()) { - supported.remove(AmqpProtocolVersion.v0_9_1); + store = new ManagementModeStoreHandler(store, options); } - if((exclude_0_9.contains(port) || !serverConfig.isAmqp09enabled()) && !include_0_9.contains(port)) + _applicationRegistry = new ApplicationRegistry(store); + try { - supported.remove(AmqpProtocolVersion.v0_9); + _applicationRegistry.initialise(); } - - if((exclude_0_8.contains(port) || !serverConfig.isAmqp08enabled()) && !include_0_8.contains(port)) + catch(Exception e) { - supported.remove(AmqpProtocolVersion.v0_8); + try + { + _applicationRegistry.close(); + } + catch(Exception ce) + { + LOGGER.debug("An error occured when closing the registry following initialization failure", ce); + } + throw e; } - return supported; } + private File getConfigFile(final String fileName, final String defaultFileName, final String qpidHome, boolean throwOnFileNotFound) throws InitException @@ -368,11 +174,11 @@ public class Broker if (!configFile.exists() && throwOnFileNotFound) { - String error = "File " + fileName + " could not be found. Check the file exists and is readable."; + String error = "File " + configFile + " could not be found. Check the file exists and is readable."; if (qpidHome == null) { - error = error + "\nNote: " + BrokerOptions.QPID_HOME + " is not set."; + error = error + "\nNote: " + BrokerProperties.PROPERTY_QPID_HOME + " is not set."; } throw new InitException(error, null); @@ -399,37 +205,6 @@ public class Broker } } - /** - * Update the configuration data with the management port. - * @param configuration - * @param registryServerPort The string from the command line - */ - private void updateManagementPorts(ServerConfiguration configuration, Integer registryServerPort, Integer connectorServerPort) - { - if (registryServerPort != null) - { - try - { - configuration.setJMXPortRegistryServer(registryServerPort); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid management (registry server) port: " + registryServerPort, null); - } - } - if (connectorServerPort != null) - { - try - { - configuration.setJMXPortConnectorServer(connectorServerPort); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid management (connector server) port: " + connectorServerPort, null); - } - } - } - private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException { if (logConfigFile.exists() && logConfigFile.canRead()) @@ -443,7 +218,7 @@ public class Broker // log4j expects the watch interval in milliseconds try { - LoggingFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000); + LoggingManagementFacade.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000); } catch (Exception e) { @@ -454,7 +229,7 @@ public class Broker { try { - LoggingFacade.configure(logConfigFile.getPath()); + LoggingManagementFacade.configure(logConfigFile.getPath()); } catch (Exception e) { @@ -531,6 +306,24 @@ public class Broker LOGGER.debug("Skipping shutdown hook removal as there either isnt one, or we are it."); } } + /** + * Workaround that prevents AMQShortStrings cache from being left in the thread local. This is important + * when embedding the Broker in containers where the starting thread may not belong to Qpid. + * The long term solution here is to stop our use of AMQShortString outside the AMQP transport layer. + */ + private void clearAMQShortStringCache() + { + AMQShortString.clearLocalCache(); + } + + public org.apache.qpid.server.model.Broker getBroker() + { + if (_applicationRegistry == null) + { + return null; + } + return _applicationRegistry.getBroker(); + } private class ShutdownService implements Runnable { @@ -540,4 +333,5 @@ public class Broker Broker.this.shutdown(); } } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java index 434d40d557..57e401e608 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -20,66 +20,25 @@ */ package org.apache.qpid.server; -import org.osgi.framework.BundleContext; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - public class BrokerOptions { - public static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; + public static final String DEFAULT_STORE_TYPE = "json"; + public static final String DEFAULT_CONFIG_FILE = "config"; public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml"; - public static final String QPID_HOME = "QPID_HOME"; - public static final String QPID_WORK = "QPID_WORK"; - - private final Set<Integer> _ports = new HashSet<Integer>(); - private final Set<Integer> _sslPorts = new HashSet<Integer>(); - private final Map<ProtocolExclusion,Set<Integer>> _exclusionMap = new HashMap<ProtocolExclusion, Set<Integer>>(); - private final Map<ProtocolInclusion,Set<Integer>> _inclusionMap = new HashMap<ProtocolInclusion, Set<Integer>>(); - private String _configFile; private String _logConfigFile; - private String _bind; - private Integer _jmxPortRegistryServer; - private Integer _jmxPortConnectorServer; - private BundleContext _bundleContext; - private Integer _logWatchFrequency = 0; - private String _qpidWorkFolder; - private String _qpidHomeFolder; - public void addPort(final int port) - { - _ports.add(port); - } + private String _configurationStoreLocation; + private String _configurationStoreType = DEFAULT_STORE_TYPE; - public void addSSLPort(final int sslPort) - { - _sslPorts.add(sslPort); - } + private String _initialConfigurationStoreLocation; + private String _initialConfigurationStoreType = DEFAULT_STORE_TYPE; - public Set<Integer> getPorts() - { - return Collections.unmodifiableSet(_ports); - } - - public Set<Integer> getSSLPorts() - { - return Collections.unmodifiableSet(_sslPorts); - } - - public String getConfigFile() - { - return _configFile; - } - - public void setConfigFile(final String configFile) - { - _configFile = configFile; - } + private boolean _managementMode; + private int _managementModeRmiPort; + private int _managementModeConnectorPort; + private int _managementModeHttpPort; public String getLogConfigFile() { @@ -91,110 +50,97 @@ public class BrokerOptions _logConfigFile = logConfigFile; } - public Integer getJmxPortRegistryServer() + public int getLogWatchFrequency() { - return _jmxPortRegistryServer; + return _logWatchFrequency; } - public void setJmxPortRegistryServer(final int jmxPortRegistryServer) + /** + * Set the frequency with which the log config file will be checked for updates. + * @param logWatchFrequency frequency in seconds + */ + public void setLogWatchFrequency(final int logWatchFrequency) { - _jmxPortRegistryServer = jmxPortRegistryServer; + _logWatchFrequency = logWatchFrequency; } - public Integer getJmxPortConnectorServer() + public String getConfigurationStoreLocation() { - return _jmxPortConnectorServer; + return _configurationStoreLocation; } - public void setJmxPortConnectorServer(final int jmxPortConnectorServer) + public void setConfigurationStoreLocation(String cofigurationStore) { - _jmxPortConnectorServer = jmxPortConnectorServer; + _configurationStoreLocation = cofigurationStore; } - public String getQpidHome() + + public String getConfigurationStoreType() { - return _qpidHomeFolder == null? System.getProperty(QPID_HOME): _qpidHomeFolder; + return _configurationStoreType; } - public Set<Integer> getExcludedPorts(final ProtocolExclusion excludeProtocol) + public void setConfigurationStoreType(String cofigurationStoreType) { - final Set<Integer> excludedPorts = _exclusionMap.get(excludeProtocol); - return excludedPorts == null ? Collections.<Integer>emptySet() : excludedPorts; + _configurationStoreType = cofigurationStoreType; } - public void addExcludedPort(final ProtocolExclusion excludeProtocol, final int port) + public void setInitialConfigurationStoreLocation(String initialConfigurationStore) { - if (!_exclusionMap.containsKey(excludeProtocol)) - { - _exclusionMap.put(excludeProtocol, new HashSet<Integer>()); - } - - Set<Integer> ports = _exclusionMap.get(excludeProtocol); - ports.add(port); + _initialConfigurationStoreLocation = initialConfigurationStore; } - public String getBind() + public void setInitialConfigurationStoreType(String initialConfigurationStoreType) { - return _bind; + _initialConfigurationStoreType = initialConfigurationStoreType; } - public void setBind(final String bind) + public String getInitialConfigurationStoreLocation() { - _bind = bind; + return _initialConfigurationStoreLocation; } - public int getLogWatchFrequency() + public String getInitialConfigurationStoreType() { - return _logWatchFrequency; + return _initialConfigurationStoreType; } - /** - * Set the frequency with which the log config file will be checked for updates. - * @param logWatchFrequency frequency in seconds - */ - public void setLogWatchFrequency(final int logWatchFrequency) + public boolean isManagementMode() { - _logWatchFrequency = logWatchFrequency; + return _managementMode; } - public BundleContext getBundleContext() + public void setManagementMode(boolean managementMode) { - return _bundleContext ; + _managementMode = managementMode; } - public void setBundleContext(final BundleContext bundleContext) + public int getManagementModeRmiPort() { - _bundleContext = bundleContext; + return _managementModeRmiPort; } - public Set<Integer> getIncludedPorts(final ProtocolInclusion includeProtocol) + public void setManagementModeRmiPort(int managementModeRmiPort) { - final Set<Integer> includedPorts = _inclusionMap.get(includeProtocol); - return includedPorts == null ? Collections.<Integer>emptySet() : includedPorts; + _managementModeRmiPort = managementModeRmiPort; } - public void addIncludedPort(final ProtocolInclusion includeProtocol, final int port) + public int getManagementModeConnectorPort() { - if (!_inclusionMap.containsKey(includeProtocol)) - { - _inclusionMap.put(includeProtocol, new HashSet<Integer>()); - } - - Set<Integer> ports = _inclusionMap.get(includeProtocol); - ports.add(port); + return _managementModeConnectorPort; } - public String getQpidWork() + public void setManagementModeConnectorPort(int managementModeConnectorPort) { - return _qpidWorkFolder; + _managementModeConnectorPort = managementModeConnectorPort; } - public void setQpidWork(String qpidWorkFolder) + public int getManagementModeHttpPort() { - _qpidWorkFolder = qpidWorkFolder; + return _managementModeHttpPort; } - public void setQpidHome(String qpidHomeFolder) + public void setManagementModeHttpPort(int managementModeHttpPort) { - _qpidHomeFolder = qpidHomeFolder; + _managementModeHttpPort = managementModeHttpPort; } }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java index 9fe7a6619f..4927956c6c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -30,9 +30,6 @@ import org.apache.commons.cli.PosixParser; import org.apache.log4j.Logger; import org.apache.qpid.common.QpidProperties; import org.apache.qpid.framing.ProtocolVersion; -import org.apache.qpid.server.Broker.InitException; -import org.apache.qpid.server.registry.ApplicationRegistry; - /** * Main entry point for AMQPD. @@ -45,86 +42,17 @@ public class Main private static final Option OPTION_VERSION = new Option("v", "version", false, "print the version information and exit"); - private static final Option OPTION_CONFIG_FILE = - OptionBuilder.withArgName("file").hasArg().withDescription("use given configuration file").withLongOpt("config") - .create("c"); - - private static final Option OPTION_PORT = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified port. Overrides any value in the config file") - .withLongOpt("port").create("p"); - - private static final Option OPTION_SSLPORT = - OptionBuilder.withArgName("port").hasArg() - .withDescription("SSL port. Overrides any value in the config file") - .withLongOpt("sslport").create("s"); - - - private static final Option OPTION_EXCLUDE_1_0 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP1-0 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-1-0").create(); - - private static final Option OPTION_EXCLUDE_0_10 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-10 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-10").create(); - - private static final Option OPTION_EXCLUDE_0_9_1 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-9-1 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-9-1").create(); - - private static final Option OPTION_EXCLUDE_0_9 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-9 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-9").create(); - - private static final Option OPTION_EXCLUDE_0_8 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("when listening on the specified port do not accept AMQP0-8 connections. The specified port must be one specified on the command line") - .withLongOpt("exclude-0-8").create(); - - private static final Option OPTION_INCLUDE_1_0 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP1-0 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-1-0").create(); - -private static final Option OPTION_INCLUDE_0_10 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-10 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-10").create(); - -private static final Option OPTION_INCLUDE_0_9_1 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-9-1 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-9-1").create(); - -private static final Option OPTION_INCLUDE_0_9 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-9 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-9").create(); - -private static final Option OPTION_INCLUDE_0_8 = - OptionBuilder.withArgName("port").hasArg() - .withDescription("accept AMQP0-8 connections on this port, overriding configuration to the contrary. The specified port must be one specified on the command line") - .withLongOpt("include-0-8").create(); - - - private static final Option OPTION_JMX_PORT_REGISTRY_SERVER = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified management (registry server) port. Overrides any value in the config file") - .withLongOpt("jmxregistryport").create("m"); - - private static final Option OPTION_JMX_PORT_CONNECTOR_SERVER = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified management (connector server) port. Overrides any value in the config file") - .withLongOpt("jmxconnectorport").create(); - - private static final Option OPTION_BIND = - OptionBuilder.withArgName("address").hasArg() - .withDescription("bind to the specified address. Overrides any value in the config file") - .withLongOpt("bind").create("b"); + private static final Option OPTION_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg() + .withDescription("use given configuration store location").withLongOpt("store-path").create("sp"); + + private static final Option OPTION_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg() + .withDescription("use given store type").withLongOpt("store-type").create("st"); + + private static final Option OPTION_INITIAL_CONFIGURATION_STORE_PATH = OptionBuilder.withArgName("path").hasArg() + .withDescription("pass the location of initial store to use to create a user store").withLongOpt("initial-store-path").create("isp"); + + private static final Option OPTION_INITIAL_CONFIGURATION_STORE_TYPE = OptionBuilder.withArgName("type").hasArg() + .withDescription("the type of initial store").withLongOpt("initial-store-type").create("ist"); private static final Option OPTION_LOG_CONFIG_FILE = OptionBuilder.withArgName("file").hasArg() @@ -137,31 +65,31 @@ private static final Option OPTION_INCLUDE_0_8 = .withDescription("monitor the log file configuration file for changes. Units are seconds. " + "Zero means do not check for changes.").withLongOpt("logwatch").create("w"); + private static final Option OPTION_MANAGEMENT_MODE = OptionBuilder.withDescription("start broker in a management mode") + .withLongOpt("management-mode").create("mm"); + private static final Option OPTION_RMI_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override jmx rmi port in management mode").withLongOpt("jmxregistryport").create("rmi"); + private static final Option OPTION_CONNECTOR_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override jmx connector port in management mode").withLongOpt("jmxconnectorport").create("jmxrmi"); + private static final Option OPTION_HTTP_PORT = OptionBuilder.withArgName("port").hasArg() + .withDescription("override web management port in management mode").withLongOpt("httpport").create("http"); + private static final Options OPTIONS = new Options(); static { OPTIONS.addOption(OPTION_HELP); OPTIONS.addOption(OPTION_VERSION); - OPTIONS.addOption(OPTION_CONFIG_FILE); + OPTIONS.addOption(OPTION_CONFIGURATION_STORE_PATH); + OPTIONS.addOption(OPTION_CONFIGURATION_STORE_TYPE); OPTIONS.addOption(OPTION_LOG_CONFIG_FILE); OPTIONS.addOption(OPTION_LOG_WATCH); - OPTIONS.addOption(OPTION_PORT); - OPTIONS.addOption(OPTION_SSLPORT); - OPTIONS.addOption(OPTION_EXCLUDE_1_0); - OPTIONS.addOption(OPTION_EXCLUDE_0_10); - OPTIONS.addOption(OPTION_EXCLUDE_0_9_1); - OPTIONS.addOption(OPTION_EXCLUDE_0_9); - OPTIONS.addOption(OPTION_EXCLUDE_0_8); - OPTIONS.addOption(OPTION_INCLUDE_1_0); - OPTIONS.addOption(OPTION_INCLUDE_0_10); - OPTIONS.addOption(OPTION_INCLUDE_0_9_1); - OPTIONS.addOption(OPTION_INCLUDE_0_9); - OPTIONS.addOption(OPTION_INCLUDE_0_8); - OPTIONS.addOption(OPTION_BIND); - - OPTIONS.addOption(OPTION_JMX_PORT_REGISTRY_SERVER); - OPTIONS.addOption(OPTION_JMX_PORT_CONNECTOR_SERVER); + OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_PATH); + OPTIONS.addOption(OPTION_INITIAL_CONFIGURATION_STORE_TYPE); + OPTIONS.addOption(OPTION_MANAGEMENT_MODE); + OPTIONS.addOption(OPTION_RMI_PORT); + OPTIONS.addOption(OPTION_CONNECTOR_PORT); + OPTIONS.addOption(OPTION_HTTP_PORT); } protected CommandLine _commandLine; @@ -243,10 +171,15 @@ private static final Option OPTION_INCLUDE_0_8 = else { BrokerOptions options = new BrokerOptions(); - String configFile = _commandLine.getOptionValue(OPTION_CONFIG_FILE.getOpt()); - if(configFile != null) + String configurationStore = _commandLine.getOptionValue(OPTION_CONFIGURATION_STORE_PATH.getOpt()); + if (configurationStore != null) + { + options.setConfigurationStoreLocation(configurationStore); + } + String configurationStoreType = _commandLine.getOptionValue(OPTION_CONFIGURATION_STORE_TYPE.getOpt()); + if (configurationStoreType != null) { - options.setConfigFile(configFile); + options.setConfigurationStoreType(configurationStoreType); } String logWatchConfig = _commandLine.getOptionValue(OPTION_LOG_WATCH.getOpt()); @@ -261,52 +194,37 @@ private static final Option OPTION_INCLUDE_0_8 = options.setLogConfigFile(logConfig); } - String jmxPortRegistryServer = _commandLine.getOptionValue(OPTION_JMX_PORT_REGISTRY_SERVER.getOpt()); - if(jmxPortRegistryServer != null) + String initialConfigurationStore = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_PATH.getOpt()); + if (initialConfigurationStore != null) { - options.setJmxPortRegistryServer(Integer.parseInt(jmxPortRegistryServer)); + options.setInitialConfigurationStoreLocation(initialConfigurationStore); } - - String jmxPortConnectorServer = _commandLine.getOptionValue(OPTION_JMX_PORT_CONNECTOR_SERVER.getLongOpt()); - if(jmxPortConnectorServer != null) - { - options.setJmxPortConnectorServer(Integer.parseInt(jmxPortConnectorServer)); - } - - String bindAddr = _commandLine.getOptionValue(OPTION_BIND.getOpt()); - if (bindAddr != null) + String initailConfigurationStoreType = _commandLine.getOptionValue(OPTION_INITIAL_CONFIGURATION_STORE_TYPE.getOpt()); + if (initailConfigurationStoreType != null) { - options.setBind(bindAddr); + options.setInitialConfigurationStoreType(initailConfigurationStoreType); } - String[] portStr = _commandLine.getOptionValues(OPTION_PORT.getOpt()); - if(portStr != null) + boolean managmentMode = _commandLine.hasOption(OPTION_MANAGEMENT_MODE.getOpt()); + if (managmentMode) { - parsePortArray(options, portStr, false); - for(ProtocolExclusion pe : ProtocolExclusion.values()) + options.setManagementMode(true); + String rmiPort = _commandLine.getOptionValue(OPTION_RMI_PORT.getOpt()); + if (rmiPort != null) { - parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe); + options.setManagementModeRmiPort(Integer.parseInt(rmiPort)); } - for(ProtocolInclusion pe : ProtocolInclusion.values()) + String connectorPort = _commandLine.getOptionValue(OPTION_CONNECTOR_PORT.getOpt()); + if (connectorPort != null) { - parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe); + options.setManagementModeConnectorPort(Integer.parseInt(connectorPort)); } - } - - String[] sslPortStr = _commandLine.getOptionValues(OPTION_SSLPORT.getOpt()); - if(sslPortStr != null) - { - parsePortArray(options, sslPortStr, true); - for(ProtocolExclusion pe : ProtocolExclusion.values()) + String httpPort = _commandLine.getOptionValue(OPTION_HTTP_PORT.getOpt()); + if (httpPort != null) { - parsePortArray(options, _commandLine.getOptionValues(pe.getExcludeName()), pe); - } - for(ProtocolInclusion pe : ProtocolInclusion.values()) - { - parseProtocolInclusions(options, _commandLine.getOptionValues(pe.getIncludeName()), pe); + options.setManagementModeHttpPort(Integer.parseInt(httpPort)); } } - setExceptionHandler(); startBroker(options); @@ -389,72 +307,7 @@ private static final Option OPTION_INCLUDE_0_8 = protected void shutdown(final int status) { - ApplicationRegistry.remove(); System.exit(status); } - private static void parsePortArray(final BrokerOptions options,final Object[] ports, - final boolean ssl) throws InitException - { - if(ports != null) - { - for(int i = 0; i < ports.length; i++) - { - try - { - if(ssl) - { - options.addSSLPort(Integer.parseInt(String.valueOf(ports[i]))); - } - else - { - options.addPort(Integer.parseInt(String.valueOf(ports[i]))); - } - } - catch (NumberFormatException e) - { - throw new InitException("Invalid port: " + ports[i], e); - } - } - } - } - - private static void parsePortArray(final BrokerOptions options, final Object[] ports, - final ProtocolExclusion excludedProtocol) throws InitException - { - if(ports != null) - { - for(int i = 0; i < ports.length; i++) - { - try - { - options.addExcludedPort(excludedProtocol, - Integer.parseInt(String.valueOf(ports[i]))); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid port for exclusion: " + ports[i], e); - } - } - } - } - - private static void parseProtocolInclusions(final BrokerOptions options, final Object[] ports, - final ProtocolInclusion includedProtocol) throws InitException - { - if(ports != null) - { - for(int i = 0; i < ports.length; i++) - { - try - { - options.addIncludedPort(includedProtocol, Integer.parseInt(String.valueOf(ports[i]))); - } - catch (NumberFormatException e) - { - throw new InitException("Invalid port for inclusion: " + ports[i], e); - } - } - } - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java b/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java deleted file mode 100644 index fe6e32173f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server; - -import java.util.HashMap; -import java.util.Map; - -public enum ProtocolExclusion -{ - v0_8("exclude-0-8","--exclude-0-8"), - v0_9("exclude-0-9", "--exclude-0-9"), - v0_9_1("exclude-0-9-1", "--exclude-0-9-1"), - v0_10("exclude-0-10", "--exclude-0-10"), - v1_0("exclude-1-0", "--exclude-1-0"); - - private static final Map<String, ProtocolExclusion> MAP = new HashMap<String,ProtocolExclusion>(); - - static - { - for(ProtocolExclusion pe : ProtocolExclusion.values()) - { - MAP.put(pe.getArg(), pe); - } - } - - private String _arg; - private String _excludeName; - - private ProtocolExclusion(final String excludeName, final String arg) - { - _excludeName = excludeName; - _arg = arg; - } - - public String getArg() - { - return _arg; - } - - public String getExcludeName() - { - return _excludeName; - } - - public static ProtocolExclusion lookup(final String arg) - { - ProtocolExclusion ex = MAP.get(arg); - - if(ex == null) - { - throw new IllegalArgumentException(arg + " is not a valid protocol exclusion"); - } - - return ex; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java b/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java deleted file mode 100644 index 85fbe2e02e..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/ProtocolInclusion.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server; - -import java.util.HashMap; -import java.util.Map; - -public enum ProtocolInclusion -{ - v0_8("include-0-8","--include-0-8"), - v0_9("include-0-9", "--include-0-9"), - v0_9_1("include-0-9-1", "--include-0-9-1"), - v0_10("include-0-10", "--include-0-10"), - v1_0("include-1-0", "--include-1-0"); - - private static final Map<String, ProtocolInclusion> MAP = new HashMap<String,ProtocolInclusion>(); - - static - { - for(ProtocolInclusion pe : ProtocolInclusion.values()) - { - MAP.put(pe.getArg(), pe); - } - } - - private String _arg; - private String _includeName; - - private ProtocolInclusion(final String includeName, final String arg) - { - _includeName = includeName; - _arg = arg; - } - - public String getArg() - { - return _arg; - } - - public String getIncludeName() - { - return _includeName; - } - - public static ProtocolInclusion lookup(final String arg) - { - ProtocolInclusion ex = MAP.get(arg); - - if(ex == null) - { - throw new IllegalArgumentException(arg + " is not a valid protocol inclusion"); - } - - return ex; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java index 0c474cca13..b7007bf768 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java +++ b/java/broker/src/main/java/org/apache/qpid/server/TransactionTimeoutHelper.java @@ -18,46 +18,85 @@ */ package org.apache.qpid.server; -import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogMessage; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.ChannelMessages; +import org.apache.qpid.server.txn.ServerTransaction; public class TransactionTimeoutHelper { - private static final Logger LOGGER = Logger.getLogger(TransactionTimeoutHelper.class); - - public static final String IDLE_TRANSACTION_ALERT = "IDLE TRANSACTION ALERT"; - public static final String OPEN_TRANSACTION_ALERT = "OPEN TRANSACTION ALERT"; + private static final String OPEN_TRANSACTION_TIMEOUT_ERROR = "Open transaction timed out"; + private static final String IDLE_TRANSACTION_TIMEOUT_ERROR = "Idle transaction timed out"; private final LogSubject _logSubject; - public TransactionTimeoutHelper(final LogSubject logSubject) + private final CloseAction _closeAction; + + public TransactionTimeoutHelper(final LogSubject logSubject, final CloseAction closeAction) { _logSubject = logSubject; + _closeAction = closeAction; } - public void logIfNecessary(final long timeSoFar, final long warnTimeout, - final LogMessage message, final String alternateLogPrefix) + public void checkIdleOrOpenTimes(ServerTransaction transaction, long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException { - if (isTimedOut(timeSoFar, warnTimeout)) + if (transaction.isTransactional()) { - LogActor logActor = CurrentActor.get(); - if(logActor.getRootMessageLogger().isMessageEnabled(logActor, _logSubject, message.getLogHierarchy())) + final long transactionUpdateTime = transaction.getTransactionUpdateTime(); + if(transactionUpdateTime > 0) { - logActor.message(_logSubject, message); + long idleTime = System.currentTimeMillis() - transactionUpdateTime; + boolean closed = logAndCloseIfNecessary(idleTime, idleWarn, idleClose, ChannelMessages.IDLE_TXN(idleTime), IDLE_TRANSACTION_TIMEOUT_ERROR); + if (closed) + { + return; // no point proceeding to check the open time + } } - else + + final long transactionStartTime = transaction.getTransactionStartTime(); + if(transactionStartTime > 0) { - LOGGER.warn(alternateLogPrefix + " " + _logSubject.toLogString() + " " + timeSoFar + " ms"); + long openTime = System.currentTimeMillis() - transactionStartTime; + logAndCloseIfNecessary(openTime, openWarn, openClose, ChannelMessages.OPEN_TXN(openTime), OPEN_TRANSACTION_TIMEOUT_ERROR); } } } - public boolean isTimedOut(long timeSoFar, long timeout) + /** + * @return true iff closeTimeout was exceeded + */ + private boolean logAndCloseIfNecessary(final long timeSoFar, + final long warnTimeout, final long closeTimeout, + final LogMessage warnMessage, final String closeMessage) throws AMQException + { + if (isTimedOut(timeSoFar, warnTimeout)) + { + LogActor logActor = CurrentActor.get(); + logActor.message(_logSubject, warnMessage); + } + + if(isTimedOut(timeSoFar, closeTimeout)) + { + _closeAction.doTimeoutAction(closeMessage); + return true; + } + else + { + return false; + } + } + + private boolean isTimedOut(long timeSoFar, long timeout) { return timeout > 0L && timeSoFar > timeout; } + + public interface CloseAction + { + void doTimeoutAction(String reason) throws AMQException; + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java index 9b3be624e0..469a4bb9d0 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java +++ b/java/broker/src/main/java/org/apache/qpid/server/binding/Binding.java @@ -35,13 +35,15 @@ public class Binding private final Exchange _exchange; private final Map<String, Object> _arguments; private final UUID _id; - private final UUID _qmfId; private final AtomicLong _matches = new AtomicLong(); - public Binding(UUID id, UUID qmfId, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments) + public Binding(UUID id, + final String bindingKey, + final AMQQueue queue, + final Exchange exchange, + final Map<String, Object> arguments) { _id = id; - _qmfId = qmfId; _bindingKey = bindingKey; _queue = queue; _exchange = exchange; @@ -53,11 +55,6 @@ public class Binding return _id; } - public UUID getQMFId() - { - return _qmfId; - } - public String getBindingKey() { return _bindingKey; diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java index b805056311..69ff081528 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java @@ -24,10 +24,6 @@ import org.apache.qpid.AMQException; import org.apache.qpid.AMQInternalException; import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.BindingConfig; -import org.apache.qpid.server.configuration.BindingConfigType; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.BindingMessages; @@ -52,7 +48,7 @@ public class BindingFactory _virtualHost = vhost; } - private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task, BindingConfig + private final class BindingImpl extends Binding implements AMQQueue.Task, Exchange.Task { private final BindingLogSubject _logSubject; //TODO : persist creation time @@ -60,7 +56,7 @@ public class BindingFactory private BindingImpl(UUID id, String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments) { - super(id, queue.getVirtualHost().getConfigStore().createId(), bindingKey, queue, exchange, arguments); + super(id, bindingKey, queue, exchange, arguments); _logSubject = new BindingLogSubject(bindingKey,exchange,queue); } @@ -96,16 +92,6 @@ public class BindingFactory return _createTime; } - public BindingConfigType getConfigType() - { - return BindingConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _virtualHost; - } - public boolean isDurable() { return getQueue().isDurable() && getExchange().isDurable(); @@ -186,7 +172,6 @@ public class BindingFactory exchange.addCloseTask(b); queue.addBinding(b); exchange.addBinding(b); - getConfigStore().addConfiguredObject(b); b.logCreation(); return true; @@ -197,11 +182,6 @@ public class BindingFactory } } - private ConfigStore getConfigStore() - { - return _virtualHost.getConfigStore(); - } - public void restoreBinding(final UUID id, final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> argumentMap) throws AMQSecurityException, AMQInternalException { makeBinding(id, bindingKey,queue,exchange,argumentMap,true, false); @@ -257,7 +237,6 @@ public class BindingFactory _virtualHost.getMessageStore().unbindQueue(b); } b.logDestruction(); - getConfigStore().removeConfiguredObject(b); } return b; diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java deleted file mode 100644 index 1ed6b38758..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfigType.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class BindingConfigType extends ConfigObjectType<BindingConfigType, BindingConfig> -{ - private static final List<BindingProperty<?>> BINDING_PROPERTIES = new ArrayList<BindingProperty<?>>(); - - public static interface BindingProperty<S> extends ConfigProperty<BindingConfigType, BindingConfig, S> - { - } - - private abstract static class BindingReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S> - { - public BindingReadWriteProperty(String name) - { - super(name); - BINDING_PROPERTIES.add(this); - } - } - - private abstract static class BindingReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BindingConfigType, BindingConfig, S> implements BindingProperty<S> - { - public BindingReadOnlyProperty(String name) - { - super(name); - BINDING_PROPERTIES.add(this); - } - } - - public static final BindingReadOnlyProperty<ExchangeConfig> EXCHANGE_PROPERTY = new BindingReadOnlyProperty<ExchangeConfig>("exchange") - { - public ExchangeConfig getValue(BindingConfig object) - { - return object.getExchange(); - } - }; - - public static final BindingReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new BindingReadOnlyProperty<QueueConfig>("queue") - { - public QueueConfig getValue(BindingConfig object) - { - return object.getQueue(); - } - }; - - public static final BindingReadOnlyProperty<String> BINDING_KEY_PROPERTY = new BindingReadOnlyProperty<String>("bindingKey") - { - public String getValue(BindingConfig object) - { - return object.getBindingKey(); - } - }; - - public static final BindingReadOnlyProperty<Map<String,Object>> ARGUMENTS = new BindingReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(BindingConfig object) - { - return object.getArguments(); - } - }; - - public static final BindingReadOnlyProperty<String> ORIGIN_PROPERTY = new BindingReadOnlyProperty<String>("origin") - { - public String getValue(BindingConfig object) - { - return object.getOrigin(); - } - }; - - private static final BindingConfigType INSTANCE = new BindingConfigType(); - - private BindingConfigType() - { - } - - public Collection<BindingProperty<?>> getProperties() - { - return Collections.unmodifiableList(BINDING_PROPERTIES); - } - - public static BindingConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java deleted file mode 100644 index 00ed5fd0dd..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -public interface BridgeConfig extends ConfiguredObject<BridgeConfigType, BridgeConfig> -{ - - boolean isDynamic(); - - boolean isQueueBridge(); - - boolean isLocalSource(); - - String getSource(); - - String getDestination(); - - String getKey(); - - String getTag(); - - String getExcludes(); - - LinkConfig getLink(); - - Integer getChannelId(); - - int getAckBatching(); -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java deleted file mode 100644 index 888feeff0c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BridgeConfigType.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class BridgeConfigType extends ConfigObjectType<BridgeConfigType, BridgeConfig> -{ - private static final List<BridgeProperty<?>> BRIDGE_PROPERTIES = new ArrayList<BridgeProperty<?>>(); - - public static interface BridgeProperty<S> extends ConfigProperty<BridgeConfigType, BridgeConfig, S> - { - } - - private abstract static class BridgeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S> - { - public BridgeReadWriteProperty(String name) - { - super(name); - BRIDGE_PROPERTIES.add(this); - } - } - - private abstract static class BridgeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BridgeConfigType, BridgeConfig, S> implements BridgeProperty<S> - { - public BridgeReadOnlyProperty(String name) - { - super(name); - BRIDGE_PROPERTIES.add(this); - } - } - - public static final BridgeReadOnlyProperty<LinkConfig> LINK_PROPERTY = new BridgeReadOnlyProperty<LinkConfig>("link") - { - public LinkConfig getValue(BridgeConfig object) - { - return object.getLink(); - } - }; - - public static final BridgeReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new BridgeReadOnlyProperty<Integer>("channelId") - { - public Integer getValue(BridgeConfig object) - { - return object.getChannelId(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> DURABLE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("durable") - { - public Boolean getValue(BridgeConfig object) - { - return object.isDurable(); - } - }; - - public static final BridgeReadOnlyProperty<String> SOURCE_PROPERTY = new BridgeReadOnlyProperty<String>("source") - { - public String getValue(BridgeConfig object) - { - return object.getSource(); - } - }; - - public static final BridgeReadOnlyProperty<String> DESTINATION_PROPERTY = new BridgeReadOnlyProperty<String>("destination") - { - public String getValue(BridgeConfig object) - { - return object.getDestination(); - } - }; - - public static final BridgeReadOnlyProperty<String> KEY_PROPERTY = new BridgeReadOnlyProperty<String>("key") - { - public String getValue(BridgeConfig object) - { - return object.getKey(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> QUEUE_BRIDGE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("queueBridge") - { - public Boolean getValue(BridgeConfig object) - { - return object.isQueueBridge(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> LOCAL_SOURCE_PROPERTY = new BridgeReadOnlyProperty<Boolean>("localSource") - { - public Boolean getValue(BridgeConfig object) - { - return object.isLocalSource(); - } - }; - - public static final BridgeReadOnlyProperty<String> TAG_PROPERTY = new BridgeReadOnlyProperty<String>("tag") - { - public String getValue(BridgeConfig object) - { - return object.getTag(); - } - }; - - public static final BridgeReadOnlyProperty<String> EXCLUDES_PROPERTY = new BridgeReadOnlyProperty<String>("excludes") - { - public String getValue(BridgeConfig object) - { - return object.getExcludes(); - } - }; - - public static final BridgeReadOnlyProperty<Boolean> DYNAMIC_PROPERTY = new BridgeReadOnlyProperty<Boolean>("dynamic") - { - public Boolean getValue(BridgeConfig object) - { - return object.isDynamic(); - } - }; - - public static final BridgeReadOnlyProperty<Integer> ACK_BATCHING_PROPERTY = new BridgeReadOnlyProperty<Integer>("ackBatching") - { - public Integer getValue(BridgeConfig object) - { - return object.getAckBatching(); - } - }; - - - private static final BridgeConfigType INSTANCE = new BridgeConfigType(); - - private BridgeConfigType() - { - } - - public Collection<BridgeProperty<?>> getProperties() - { - return Collections.unmodifiableList(BRIDGE_PROPERTIES); - } - - public static BridgeConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java deleted file mode 100644 index 7dffc2d3c0..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfig.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.List; - - -public interface BrokerConfig extends ConfiguredObject<BrokerConfigType,BrokerConfig> -{ - void setSystem(SystemConfig system); - - SystemConfig getSystem(); - - Integer getPort(); - - Integer getWorkerThreads(); - - Integer getMaxConnections(); - - Integer getConnectionBacklogLimit(); - - Long getStagingThreshold(); - - Integer getManagementPublishInterval(); - - String getVersion(); - - String getDataDirectory(); - - String getFederationTag(); - - /** - * List of feature(s) to be advertised to clients on connection. - * Feature names are strings, beginning with qpid. followed by more or more - * words separated by minus signs e.g. qpid.jms-selector. - * - * If there are no features, this method must return an empty array. - * - * @return list of feature names - */ - List<String> getFeatures(); - - void addVirtualHost(VirtualHostConfig virtualHost); - - void createBrokerConnection(String transport, - String host, - int port, - boolean durable, - String authMechanism, - String username, String password); - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java deleted file mode 100644 index 64a59c3f61..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigType.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class BrokerConfigType extends ConfigObjectType<BrokerConfigType, BrokerConfig> -{ - private static final List<BrokerProperty<?>> BROKER_PROPERTIES = new ArrayList<BrokerProperty<?>>(); - - public static interface BrokerProperty<S> extends ConfigProperty<BrokerConfigType, BrokerConfig, S> - { - } - - private abstract static class BrokerReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S> - { - public BrokerReadWriteProperty(String name) - { - super(name); - BROKER_PROPERTIES.add(this); - } - } - - private abstract static class BrokerReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<BrokerConfigType, BrokerConfig, S> implements BrokerProperty<S> - { - public BrokerReadOnlyProperty(String name) - { - super(name); - BROKER_PROPERTIES.add(this); - } - } - - public static final BrokerReadOnlyProperty<SystemConfig> SYSTEM_PROPERTY = new BrokerReadOnlyProperty<SystemConfig>("system") - { - public SystemConfig getValue(BrokerConfig object) - { - return object.getSystem(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> PORT_PROPERTY = new BrokerReadOnlyProperty<Integer>("port") - { - public Integer getValue(BrokerConfig object) - { - return object.getPort(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> WORKER_THREADS_PROPERTY = new BrokerReadOnlyProperty<Integer>("workerThreads") - { - public Integer getValue(BrokerConfig object) - { - return object.getWorkerThreads(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> MAX_CONNECTIONS_PROPERTY = new BrokerReadOnlyProperty<Integer>("maxConnections") - { - public Integer getValue(BrokerConfig object) - { - return object.getMaxConnections(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> CONNECTION_BACKLOG_LIMIT_PROPERTY = new BrokerReadOnlyProperty<Integer>("connectionBacklog") - { - public Integer getValue(BrokerConfig object) - { - return object.getConnectionBacklogLimit(); - } - }; - - public static final BrokerReadOnlyProperty<Long> STAGING_THRESHOLD_PROPERTY = new BrokerReadOnlyProperty<Long>("stagingThreshold") - { - public Long getValue(BrokerConfig object) - { - return object.getStagingThreshold(); - } - }; - - public static final BrokerReadOnlyProperty<Integer> MANAGEMENT_PUBLISH_INTERVAL_PROPERTY = new BrokerReadOnlyProperty<Integer>("mgmtPublishInterval") - { - public Integer getValue(BrokerConfig object) - { - return object.getManagementPublishInterval(); - } - }; - - public static final BrokerReadOnlyProperty<String> VERSION_PROPERTY = new BrokerReadOnlyProperty<String>("version") - { - public String getValue(BrokerConfig object) - { - return object.getVersion(); - } - }; - - public static final BrokerReadOnlyProperty<String> DATA_DIR_PROPERTY = new BrokerReadOnlyProperty<String>("dataDirectory") - { - public String getValue(BrokerConfig object) - { - return object.getDataDirectory(); - } - }; - - private static final BrokerConfigType INSTANCE = new BrokerConfigType(); - - private BrokerConfigType() - { - } - - public Collection<BrokerProperty<?>> getProperties() - { - return Collections.unmodifiableList(BROKER_PROPERTIES); - } - - public static BrokerConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java new file mode 100644 index 0000000000..31e08ab88a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerConfigurationStoreCreator.java @@ -0,0 +1,102 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +/** + * A helper class responsible for creation and opening of broker store. + */ +public class BrokerConfigurationStoreCreator +{ + /** + * URL to resource containing broker default configuration + */ + public static final String DEFAULT_INITIAL_STORE_LOCATION = BrokerConfigurationStoreCreator.class.getClassLoader() + .getResource("initial-store.json").toExternalForm(); + + private Map<String, ConfigurationStoreFactory> _factories = new HashMap<String, ConfigurationStoreFactory>(); + + public BrokerConfigurationStoreCreator() + { + QpidServiceLoader<ConfigurationStoreFactory> serviceLoader = new QpidServiceLoader<ConfigurationStoreFactory>(); + Iterable<ConfigurationStoreFactory> configurationStoreFactories = serviceLoader + .instancesOf(ConfigurationStoreFactory.class); + for (ConfigurationStoreFactory storeFactory : configurationStoreFactories) + { + String type = storeFactory.getStoreType(); + ConfigurationStoreFactory factory = _factories.put(type.toLowerCase(), storeFactory); + if (factory != null) + { + throw new IllegalStateException("ConfigurationStoreFactory with type name '" + type + + "' is already registered using class '" + factory.getClass().getName() + "', can not register class '" + + storeFactory.getClass().getName() + "'"); + } + } + } + + /** + * Create broker configuration store for a given store location, store type, initial store location and initial store type + * + * @param storeLocation store location + * @param storeType store type + * @param initialStoreLocation initial store location + * @param initialStoreType initial store type + * @return store instance opened at given store location + * @throws IllegalConfigurationException if store type is unknown + */ + public ConfigurationEntryStore createStore(String storeLocation, String storeType, String initialStoreLocation, + String initialStoreType) + { + ConfigurationEntryStore store = createStore(storeType); + if (initialStoreLocation == null) + { + initialStoreLocation = DEFAULT_INITIAL_STORE_LOCATION; + initialStoreType = JsonConfigurationEntryStore.STORE_TYPE; + } + if (storeType.equals(initialStoreType)) + { + store.open(storeLocation, initialStoreLocation); + } + else + { + ConfigurationEntryStore initialStore = createStore(initialStoreType); + initialStore.open(initialStoreLocation); + store.open(storeLocation, initialStore); + } + return store; + } + + private ConfigurationEntryStore createStore(String storeType) + { + ConfigurationStoreFactory factory = _factories.get(storeType.toLowerCase()); + if (factory == null) + { + throw new IllegalConfigurationException("Unknown store type: " + storeType); + } + return factory.createStore(); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java new file mode 100644 index 0000000000..179d4a5640 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/BrokerProperties.java @@ -0,0 +1,54 @@ +package org.apache.qpid.server.configuration; + +import java.util.Locale; + +/** + * Declares broker system property names + */ +public class BrokerProperties +{ + public static final int DEFAULT_HEART_BEAT_TIMEOUT_FACTOR = 2; + + public static final String PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX = "qpid.dead_letter_exchange_suffix"; + public static final String PROPERTY_DEAD_LETTER_QUEUE_SUFFIX = "qpid.dead_letter_queue_suffix"; + + public static final String PROPERTY_FRAME_SIZE = "qpid.frame_size"; + public static final String PROPERTY_MSG_AUTH = "qpid.msg_auth"; + public static final String PROPERTY_STATUS_UPDATES = "qpid.status_updates"; + public static final String PROPERTY_LOCALE = "qpid.locale"; + public static final String PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY = "qpid.default_supported_protocol_version_reply"; + public static final String PROPERTY_DISABLED_FEATURES = "qpid.broker_disabled_features"; + + public static final int DEFAULT_FRAME_SIZE = Integer.getInteger(PROPERTY_FRAME_SIZE, 65535); + public static final String PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES = "qpid.broker_default_amqp_protocol_excludes"; + public static final String PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES = "qpid.broker_default_amqp_protocol_includes"; + + public static final String PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS = "qpid.broker_jmx_method_rights_infer_all_access"; + public static final String PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY = "qpid.broker_jmx_use_custom_rmi_socket_factory"; + + public static final String PROPERTY_QPID_HOME = "QPID_HOME"; + public static final String PROPERTY_QPID_WORK = "QPID_WORK"; + + private BrokerProperties() + { + } + + public static Locale getLocale() + { + Locale locale = Locale.US; + String localeSetting = System.getProperty(BrokerProperties.PROPERTY_LOCALE); + if (localeSetting != null) + { + String[] localeParts = localeSetting.split("_"); + String language = (localeParts.length > 0 ? localeParts[0] : ""); + String country = (localeParts.length > 1 ? localeParts[1] : ""); + String variant = ""; + if (localeParts.length > 2) + { + variant = localeSetting.substring(language.length() + 1 + country.length() + 1); + } + locale = new Locale(language, country, variant); + } + return locale; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java deleted file mode 100644 index 2d88ba00a0..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigProperty.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -public interface ConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S> -{ - public String getName(); - - public S getValue(C object); - - public void setValue(C object, S value); - - public void clearValue(C object); - - public abstract static class ReadWriteConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>,S> implements ConfigProperty<T, C, S> - { - private final String _name; - - protected ReadWriteConfigProperty(String name) - { - _name = name; - } - - public final String getName() - { - return _name; - } - } - - public abstract static class ReadOnlyConfigProperty<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>, S> extends ReadWriteConfigProperty<T, C, S> - { - protected ReadOnlyConfigProperty(String name) - { - super(name); - } - - public final void setValue(C object, S value) - { - throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only"); - } - - public final void clearValue(C object) - { - throw new UnsupportedOperationException("Cannot set value '"+getName()+"' as this property is read-only"); - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java deleted file mode 100644 index c519a0c0fa..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigStore.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.Collection; -import java.util.Collections; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - -public class ConfigStore -{ - private ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>> _typeMap = - new ConcurrentHashMap<ConfigObjectType, ConcurrentHashMap<UUID, ConfiguredObject>>(); - - private ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>> _listenerMap = - new ConcurrentHashMap<ConfigObjectType, CopyOnWriteArrayList<ConfigEventListener>>(); - - private AtomicReference<SystemConfig> _root = new AtomicReference<SystemConfig>(null); - - private final AtomicLong _objectIdSource = new AtomicLong(0l); - private final AtomicLong _persistentObjectIdSource = new AtomicLong(0l); - - // TODO - should load/increment this on broker startup - private long _sequenceNumber = 1L; - - public enum Event - { - CREATED, DELETED - } - - public interface ConfigEventListener<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>> - { - void onEvent(C object, Event evt); - } - - private ConfigStore() - { - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> ConfiguredObject<T, C> getConfiguredObject(ConfigObjectType<T,C> type, UUID id) - { - ConcurrentHashMap<UUID, ConfiguredObject> typeMap = _typeMap.get(type); - if(typeMap != null) - { - return typeMap.get(id); - } - else - { - return null; - } - - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> Collection<? extends C> getConfiguredObjects(ConfigObjectType<T,C> type) - { - ConcurrentHashMap typeMap = _typeMap.get(type); - if(typeMap != null) - { - return typeMap.values(); - } - else - { - return Collections.EMPTY_LIST; - } - - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfiguredObject(ConfiguredObject<T, C> object) - { - ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType()); - if(typeMap == null) - { - typeMap = new ConcurrentHashMap(); - ConcurrentHashMap oldMap = _typeMap.putIfAbsent(object.getConfigType(), typeMap); - if(oldMap != null) - { - typeMap = oldMap; - } - - } - - typeMap.put(object.getQMFId(), object); - sendEvent(Event.CREATED, object); - } - - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfiguredObject(ConfiguredObject<T, C> object) - { - ConcurrentHashMap typeMap = _typeMap.get(object.getConfigType()); - if(typeMap != null) - { - typeMap.remove(object.getQMFId()); - sendEvent(Event.DELETED, object); - } - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void addConfigEventListener(T type, ConfigEventListener<T,C> listener) - { - CopyOnWriteArrayList listeners = _listenerMap.get(type); - if(listeners == null) - { - listeners = new CopyOnWriteArrayList(); - CopyOnWriteArrayList oldListeners = _listenerMap.putIfAbsent(type, listeners); - if(oldListeners != null) - { - listeners = oldListeners; - } - - } - - listeners.add(listener); - - } - - public <T extends ConfigObjectType<T, C>, C extends ConfiguredObject<T, C>> void removeConfigEventListener(T type, ConfigEventListener<T,C> listener) - { - CopyOnWriteArrayList listeners = _listenerMap.get(type); - if(listeners != null) - { - listeners.remove(listener); - } - } - - private void sendEvent(Event e, ConfiguredObject o) - { - CopyOnWriteArrayList<ConfigEventListener> listeners = _listenerMap.get(o.getConfigType()); - if(listeners != null) - { - for(ConfigEventListener listener : listeners) - { - listener.onEvent(o, e); - } - } - } - - public boolean setRoot(SystemConfig object) - { - if(_root.compareAndSet(null,object)) - { - addConfiguredObject(object); - return true; - } - else - { - return false; - } - } - - public UUID createId() - { - return new UUID(((_sequenceNumber & 0xFFFl)<<48), _objectIdSource.incrementAndGet()); - } - - public UUID createPersistentId() - { - return new UUID(0L, _persistentObjectIdSource.incrementAndGet()); - } - - public void persistentIdInUse(UUID id) - { - long lsb = id.getLeastSignificantBits(); - long currentId; - while((currentId = _persistentObjectIdSource.get()) < lsb) - { - _persistentObjectIdSource.compareAndSet(currentId, lsb); - } - } - - public SystemConfig getRoot() - { - return _root.get(); - } - - public static ConfigStore newInstance() - { - return new ConfigStore(); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java new file mode 100644 index 0000000000..8afb1af24d --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntry.java @@ -0,0 +1,203 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +public class ConfigurationEntry +{ + public static final String ATTRIBUTE_NAME = "name"; + + private final UUID _id; + private final String _type; + private final Map<String, Object> _attributes; + private final Set<UUID> _childrenIds; + private final ConfigurationEntryStore _store; + + public ConfigurationEntry(UUID id, String type, Map<String, Object> attributes, Set<UUID> childrenIds, + ConfigurationEntryStore store) + { + super(); + _id = id; + _type = type; + _attributes = attributes; + _childrenIds = childrenIds; + _store = store; + } + + public UUID getId() + { + return _id; + } + + public String getType() + { + return _type; + } + + public Map<String, Object> getAttributes() + { + return _attributes; + } + + public Set<UUID> getChildrenIds() + { + return _childrenIds; + } + + public ConfigurationEntryStore getStore() + { + return _store; + } + + /** + * Returns this entry's children. The collection should not be modified. + */ + public Map<String, Collection<ConfigurationEntry>> getChildren() + { + Map<String, Collection<ConfigurationEntry>> children = null; + if (_childrenIds == null) + { + children = Collections.emptyMap(); + } + else + { + children = new HashMap<String, Collection<ConfigurationEntry>>(); + for (UUID childId : _childrenIds) + { + ConfigurationEntry entry = _store.getEntry(childId); + String type = entry.getType(); + Collection<ConfigurationEntry> childrenOfType = children.get(type); + if (childrenOfType == null) + { + childrenOfType = new ArrayList<ConfigurationEntry>(); + children.put(type, childrenOfType); + } + childrenOfType.add(entry); + } + } + return Collections.unmodifiableMap(children); + } + + public boolean hasChild(UUID id) + { + return _childrenIds.contains(id); + } + + @Override + public int hashCode() + { + return _id.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + ConfigurationEntry other = (ConfigurationEntry) obj; + if (_id == null) + { + if (other._id != null) + { + return false; + } + } + else if (!_id.equals(other._id)) + { + return false; + } + + if (_type == null) + { + if (other._type != null) + { + return false; + } + } + else if (!_type.equals(other._type)) + { + return false; + } + + if (_store == null) + { + if (other._store != null) + { + return false; + } + } + else if (!_store.equals(other._store)) + { + return false; + } + + if (_childrenIds == null) + { + if (other._childrenIds != null) + { + return false; + } + } + else if (!_childrenIds.equals(other._childrenIds)) + { + return false; + } + + if (_attributes == null) + { + if (other._attributes != null) + { + return false; + } + } + else if (!_attributes.equals(other._attributes)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return "ConfigurationEntry [id=" + _id + ", type=" + _type + ", attributes=" + _attributes + ", childrenIds=" + + _childrenIds + "]"; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java new file mode 100644 index 0000000000..8238d147bd --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationEntryStore.java @@ -0,0 +1,98 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.util.UUID; + +public interface ConfigurationEntryStore +{ + /** + * Opens the store from a given location. + * <p> + * If location does not exists than a new empty store is created with a single root entry + * + * @param storeLocation store location + * @throws IllegalConfigurationException if store cannot be opened in the given location + */ + void open(String storeLocation); + + /** + * Opens the store from a given location. + * <p> + * If location does not exists than a new store is created either empty or from the initial store location if it is provided + * + * @param storeLocation store location + * @param initialStoreLocation initial store location + * @throws IllegalConfigurationException if store cannot be opened in the given location or initial store location does not + * exists or corrupted. + */ + void open(String storeLocation, String initialStoreLocation); + + /** + * Opens the store from a given location. + * <p> + * If location does not exists than a new store is created either empty or from the initial store if it is provided + * + * @param storeLocation store location + * @param initialStore initial store + * @throws IllegalConfigurationException if store cannot be opened in the given location + */ + void open(String storeLocation, ConfigurationEntryStore initialStore); + + /** + * Returns stored root configuration entry + * + * @return root entry + */ + ConfigurationEntry getRootEntry(); + + /** + * Returns the configuration entry with a given id. + * + * @return entry with a given id or null if entry does not exists + */ + ConfigurationEntry getEntry(UUID id); + + /** + * Saves given entries in the store. + * + * @param entries entries to store + * @throws IllegalConfigurationException if save operation fails + */ + void save(ConfigurationEntry... entries); + + /** + * Removes the entries with given IDs and all their children + * + * @param entryIds IDs of entries to remove + * @return IDs of removed entries + * @throws IllegalConfigurationException if remove operation fails + */ + UUID[] remove(UUID... entryIds); + + /** + * Copies the store into the given location + * + * @param target location to copy store into + * @throws IllegalConfigurationException if store cannot be copied into given location + */ + public void copyTo(String copyLocation); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java deleted file mode 100644 index 06402fa646..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationManager.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.registry.ApplicationRegistry; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public class ConfigurationManager -{ - public List<ConfigurationPlugin> getConfigurationPlugins(String configurationElement, Configuration configuration) throws ConfigurationException - { - List<ConfigurationPlugin> plugins = new ArrayList<ConfigurationPlugin>(); - Map<List<String>, ConfigurationPluginFactory> factories = - ApplicationRegistry.getInstance().getPluginManager().getConfigurationPlugins(); - - for (Entry<List<String>, ConfigurationPluginFactory> entry : factories.entrySet()) - { - if (entry.getKey().contains(configurationElement)) - { - ConfigurationPluginFactory factory = entry.getValue(); - plugins.add(factory.newInstance(configurationElement, configuration)); - } - } - - return plugins; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java index bfb2de4235..dced38d260 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigurationPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigurationStoreFactory.java @@ -20,10 +20,16 @@ */ package org.apache.qpid.server.configuration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.queue.AMQQueue; -public interface ExchangeConfigurationPlugin +public interface ConfigurationStoreFactory { - ConfigurationPlugin getConfiguration(AMQQueue queue); + /** + * Returns the type of the store this factory can create + */ + public String getStoreType(); + + /** + * Creates the store instance. + */ + public ConfigurationEntryStore createStore(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java index c45aaaf1ee..65d97e6db1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfigObjectType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObjectRecoverer.java @@ -18,13 +18,11 @@ * under the License. * */ - package org.apache.qpid.server.configuration; -import java.util.Collection; +import org.apache.qpid.server.model.ConfiguredObject; -public abstract class ConfigObjectType<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T,C>> +public interface ConfiguredObjectRecoverer<T extends ConfiguredObject> { - public abstract Collection<? extends ConfigProperty<T, C, ?>> getProperties(); - + T create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java deleted file mode 100644 index 0dd36fe1fe..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -public interface ConnectionConfig extends ConfiguredObject<ConnectionConfigType, ConnectionConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getAddress(); - - Boolean isIncoming(); - - Boolean isSystemConnection(); - - Boolean isFederationLink(); - - String getAuthId(); - - String getRemoteProcessName(); - - Integer getRemotePID(); - - Integer getRemoteParentPID(); - - ConfigStore getConfigStore(); - - Boolean isShadow(); - - void mgmtClose(); -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java deleted file mode 100644 index 5631fda37c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConnectionConfigType.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class ConnectionConfigType extends ConfigObjectType<ConnectionConfigType, ConnectionConfig> -{ - private static final List<ConnectionProperty<?>> CONNECTION_PROPERTIES = new ArrayList<ConnectionProperty<?>>(); - - public static interface ConnectionProperty<S> extends ConfigProperty<ConnectionConfigType, ConnectionConfig, S> - { - } - - private abstract static class ConnectionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S> - { - public ConnectionReadWriteProperty(String name) - { - super(name); - CONNECTION_PROPERTIES.add(this); - } - } - - private abstract static class ConnectionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ConnectionConfigType, ConnectionConfig, S> implements ConnectionProperty<S> - { - public ConnectionReadOnlyProperty(String name) - { - super(name); - CONNECTION_PROPERTIES.add(this); - } - } - - public static final ConnectionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ConnectionReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(ConnectionConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final ConnectionReadOnlyProperty<String> ADDRESS_PROPERTY = new ConnectionReadOnlyProperty<String>("address") - { - public String getValue(ConnectionConfig object) - { - return object.getAddress(); - } - }; - - public static final ConnectionReadOnlyProperty<Boolean> INCOMING_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("incoming") - { - public Boolean getValue(ConnectionConfig object) - { - return object.isIncoming(); - } - }; - - public static final ConnectionReadOnlyProperty<Boolean> SYSTEM_CONNECTION_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("systemConnection") - { - public Boolean getValue(ConnectionConfig object) - { - return object.isSystemConnection(); - } - }; - - public static final ConnectionReadOnlyProperty<Boolean> FEDERATION_LINK_PROPERTY = new ConnectionReadOnlyProperty<Boolean>("federationLink") - { - public Boolean getValue(ConnectionConfig object) - { - return object.isFederationLink(); - } - }; - - public static final ConnectionReadOnlyProperty<String> AUTH_ID_PROPERTY = new ConnectionReadOnlyProperty<String>("authId") - { - public String getValue(ConnectionConfig object) - { - return object.getAuthId(); - } - }; - - public static final ConnectionReadOnlyProperty<String> REMOTE_PROCESS_NAME_PROPERTY = new ConnectionReadOnlyProperty<String>("remoteProcessName") - { - public String getValue(ConnectionConfig object) - { - return object.getRemoteProcessName(); - } - }; - - - public static final ConnectionReadOnlyProperty<Integer> REMOTE_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remotePid") - { - public Integer getValue(ConnectionConfig object) - { - return object.getRemotePID(); - } - }; - - public static final ConnectionReadOnlyProperty<Integer> REMOTE_PARENT_PID_PROPERTY = new ConnectionReadOnlyProperty<Integer>("remoteParentPid") - { - public Integer getValue(ConnectionConfig object) - { - return object.getRemoteParentPID(); - } - }; - - private static final ConnectionConfigType INSTANCE = new ConnectionConfigType(); - - private ConnectionConfigType() - { - } - - public Collection<ConnectionProperty<?>> getProperties() - { - return Collections.unmodifiableList(CONNECTION_PROPERTIES); - } - - public static ConnectionConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java deleted file mode 100644 index 6633d93adf..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import org.apache.qpid.server.exchange.ExchangeType; - -import java.util.Map; - - -public interface ExchangeConfig extends ConfiguredObject<ExchangeConfigType, ExchangeConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getName(); - - ExchangeType getType(); - - boolean isAutoDelete(); - - ExchangeConfig getAlternateExchange(); - - Map<String, Object> getArguments(); - - - long getBindingCount(); - - long getBindingCountHigh(); - - long getMsgReceives(); - - long getMsgRoutes(); - - long getMsgDrops(); - - long getByteReceives(); - - long getByteRoutes(); - - long getByteDrops(); - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java deleted file mode 100644 index c7744117c4..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfigType.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class ExchangeConfigType extends ConfigObjectType<ExchangeConfigType, ExchangeConfig> -{ - private static final List<ExchangeProperty<?>> EXCHANGE_PROPERTIES = new ArrayList<ExchangeProperty<?>>(); - - public static interface ExchangeProperty<S> extends ConfigProperty<ExchangeConfigType, ExchangeConfig, S> - { - } - - private abstract static class ExchangeReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S> - { - public ExchangeReadWriteProperty(String name) - { - super(name); - EXCHANGE_PROPERTIES.add(this); - } - } - - private abstract static class ExchangeReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<ExchangeConfigType, ExchangeConfig, S> implements ExchangeProperty<S> - { - public ExchangeReadOnlyProperty(String name) - { - super(name); - EXCHANGE_PROPERTIES.add(this); - } - } - - public static final ExchangeReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new ExchangeReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(ExchangeConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final ExchangeReadOnlyProperty<String> NAME_PROPERTY = new ExchangeReadOnlyProperty<String>("name") - { - public String getValue(ExchangeConfig object) - { - return object.getName(); - } - }; - - public static final ExchangeReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new ExchangeReadOnlyProperty<Boolean>("autodelete") - { - public Boolean getValue(ExchangeConfig object) - { - return object.isAutoDelete(); - } - }; - - - public static final ExchangeReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new ExchangeReadOnlyProperty<ExchangeConfig>("alternateExchange") - { - public ExchangeConfig getValue(ExchangeConfig object) - { - return object.getAlternateExchange(); - } - }; - - public static final ExchangeReadOnlyProperty<Map<String,Object>> ARGUMENTS = new ExchangeReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(ExchangeConfig object) - { - return object.getArguments(); - } - }; - - private static final ExchangeConfigType INSTANCE = new ExchangeConfigType(); - - private ExchangeConfigType() - { - } - - public Collection<ExchangeProperty<?>> getProperties() - { - return Collections.unmodifiableList(EXCHANGE_PROPERTIES); - } - - public static ExchangeConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java index ff4e38d9f7..bedd470ddf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ConfiguredObject.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/IllegalConfigurationException.java @@ -18,20 +18,20 @@ * under the License. * */ - package org.apache.qpid.server.configuration; -import java.util.UUID; - -public interface ConfiguredObject<T extends ConfigObjectType<T,C>, C extends ConfiguredObject<T, C>> +public class IllegalConfigurationException extends RuntimeException { - public UUID getQMFId(); - - public T getConfigType(); + private static final long serialVersionUID = 1130064756291179812L; - public ConfiguredObject<T,C> getParent(); + public IllegalConfigurationException(String message) + { + super(message); + } - public boolean isDurable(); + public IllegalConfigurationException(String message, Throwable cause) + { + super(message, cause); + } - long getCreateTime(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java deleted file mode 100644 index 2c37a94db0..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -public interface LinkConfig extends ConfiguredObject<LinkConfigType, LinkConfig> -{ - VirtualHostConfig getVirtualHost(); - - - String getTransport(); - - String getHost(); - - int getPort(); - - String getRemoteVhost(); - - String getAuthMechanism(); - - String getUsername(); - - String getPassword(); - - void close(); - - void createBridge(boolean durable, - boolean dynamic, - boolean srcIsQueue, - boolean srcIsLocal, - String src, - String dest, - String key, String tag, String excludes); - - String getState(); - - String getLastError(); -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java deleted file mode 100644 index 847cae87f5..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/LinkConfigType.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class LinkConfigType extends ConfigObjectType<LinkConfigType, LinkConfig> -{ - private static final List<LinkProperty<?>> LINK_PROPERTIES = new ArrayList<LinkProperty<?>>(); - - public static interface LinkProperty<S> extends ConfigProperty<LinkConfigType, LinkConfig, S> - { - } - - private abstract static class LinkReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S> - { - public LinkReadWriteProperty(String name) - { - super(name); - LINK_PROPERTIES.add(this); - } - } - - private abstract static class LinkReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<LinkConfigType, LinkConfig, S> implements LinkProperty<S> - { - public LinkReadOnlyProperty(String name) - { - super(name); - LINK_PROPERTIES.add(this); - } - } - - public static final LinkReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new LinkReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(LinkConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final LinkReadOnlyProperty<String> TRANSPORT_PROPERTY = new LinkReadOnlyProperty<String>("transport") - { - public String getValue(LinkConfig object) - { - return object.getTransport(); - } - }; - - public static final LinkReadOnlyProperty<String> HOST_PROPERTY = new LinkReadOnlyProperty<String>("host") - { - public String getValue(LinkConfig object) - { - return object.getHost(); - } - }; - - public static final LinkReadOnlyProperty<Integer> PORT_PROPERTY = new LinkReadOnlyProperty<Integer>("port") - { - public Integer getValue(LinkConfig object) - { - return object.getPort(); - } - }; - - public static final LinkReadOnlyProperty<String> REMOTE_VHOST_PROPERTY = new LinkReadOnlyProperty<String>("remoteVhost") - { - public String getValue(LinkConfig object) - { - return object.getRemoteVhost(); - } - }; - - public static final LinkReadOnlyProperty<String> AUTH_MECHANISM_PROPERTY = new LinkReadOnlyProperty<String>("authMechanism") - { - public String getValue(LinkConfig object) - { - return object.getAuthMechanism(); - } - }; - - public static final LinkReadOnlyProperty<String> USERNAME_PROPERTY = new LinkReadOnlyProperty<String>("username") - { - public String getValue(LinkConfig object) - { - return object.getUsername(); - } - }; - - public static final LinkReadOnlyProperty<String> PASSWORD_PROPERTY = new LinkReadOnlyProperty<String>("password") - { - public String getValue(LinkConfig object) - { - return object.getPassword(); - } - }; - - private static final LinkConfigType INSTANCE = new LinkConfigType(); - - private LinkConfigType() - { - } - - public Collection<LinkProperty<?>> getProperties() - { - return Collections.unmodifiableList(LINK_PROPERTIES); - } - - public static LinkConfigType getInstance() - { - return INSTANCE; - } - - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java deleted file mode 100644 index 1ef5edeb51..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfig.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import org.apache.qpid.AMQException; - -import java.util.Map; - - -public interface QueueConfig extends ConfiguredObject<QueueConfigType, QueueConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getName(); - - boolean isExclusive(); - - boolean isAutoDelete(); - - ExchangeConfig getAlternateExchange(); - - Map<String, Object> getArguments(); - - long getReceivedMessageCount(); - - int getMessageCount(); - - long getQueueDepth(); - - int getConsumerCount(); - - int getConsumerCountHigh(); - - int getBindingCount(); - - int getBindingCountHigh(); - - ConfigStore getConfigStore(); - - long getMessageDequeueCount(); - - long getTotalEnqueueSize(); - - long getTotalDequeueSize(); - - long getByteTxnEnqueues(); - - long getByteTxnDequeues(); - - long getMsgTxnEnqueues(); - - long getMsgTxnDequeues(); - - long getPersistentByteEnqueues(); - - long getPersistentByteDequeues(); - - long getPersistentMsgEnqueues(); - - long getPersistentMsgDequeues(); - - long getUnackedMessageCount(); - - long getUnackedMessageCountHigh(); - - void purge(long request) throws AMQException; -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java deleted file mode 100644 index f958ef5350..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfigType.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class QueueConfigType extends ConfigObjectType<QueueConfigType, QueueConfig> -{ - private static final List<QueueProperty<?>> QUEUE_PROPERTIES = new ArrayList<QueueProperty<?>>(); - - public static interface QueueProperty<S> extends ConfigProperty<QueueConfigType, QueueConfig, S> - { - } - - private abstract static class QueueReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S> - { - public QueueReadWriteProperty(String name) - { - super(name); - QUEUE_PROPERTIES.add(this); - } - } - - private abstract static class QueueReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<QueueConfigType, QueueConfig, S> implements QueueProperty<S> - { - public QueueReadOnlyProperty(String name) - { - super(name); - QUEUE_PROPERTIES.add(this); - } - } - - public static final QueueReadOnlyProperty<VirtualHostConfig> VISTUAL_HOST_PROPERTY = new QueueReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(QueueConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final QueueReadOnlyProperty<String> NAME_PROPERTY = new QueueReadOnlyProperty<String>("name") - { - public String getValue(QueueConfig object) - { - return object.getName(); - } - }; - - public static final QueueReadOnlyProperty<Boolean> AUTODELETE_PROPERTY = new QueueReadOnlyProperty<Boolean>("autodelete") - { - public Boolean getValue(QueueConfig object) - { - return object.isAutoDelete(); - } - }; - - public static final QueueReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new QueueReadOnlyProperty<Boolean>("exclusive") - { - public Boolean getValue(QueueConfig object) - { - return object.isExclusive(); - } - }; - - public static final QueueReadOnlyProperty<ExchangeConfig> ALTERNATE_EXCHANGE_PROPERTY = new QueueReadOnlyProperty<ExchangeConfig>("alternateExchange") - { - public ExchangeConfig getValue(QueueConfig object) - { - return object.getAlternateExchange(); - } - }; - - public static final QueueReadOnlyProperty<Map<String,Object>> ARGUMENTS = new QueueReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(QueueConfig object) - { - return object.getArguments(); - } - }; - - - private static final QueueConfigType INSTANCE = new QueueConfigType(); - - private QueueConfigType() - { - } - - public Collection<QueueProperty<?>> getProperties() - { - return Collections.unmodifiableList(QUEUE_PROPERTIES); - } - - public static QueueConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java index 8f03383777..06691d8659 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java @@ -24,11 +24,11 @@ import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; import java.util.List; -public class QueueConfiguration extends ConfigurationPlugin +public class QueueConfiguration extends AbstractConfiguration { private String _name; private VirtualHostConfiguration _vHostConfig; @@ -39,7 +39,7 @@ public class QueueConfiguration extends ConfigurationPlugin _name = name; CompositeConfiguration mungedConf = new CompositeConfiguration(); - mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues.queue." + name)); + mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues.queue." + escapeTagName(name))); mungedConf.addConfiguration(_vHostConfig.getConfig().subset("queues")); setConfiguration("virtualhosts.virtualhost.queues.queue", mungedConf); @@ -193,43 +193,4 @@ public class QueueConfiguration extends ConfigurationPlugin { return getBooleanValue("deadLetterQueues", _vHostConfig.isDeadLetterQueueEnabled()); } - - public static class QueueConfig extends ConfigurationPlugin - { - @Override - public String[] getElementsProcessed() - { - return new String[]{"name"}; - } - - public String getName() - { - return getStringValue("name"); - } - - - public void validateConfiguration() throws ConfigurationException - { - if (getConfig().isEmpty()) - { - throw new ConfigurationException("Queue section cannot be empty."); - } - - if (getName() == null) - { - throw new ConfigurationException("Queue section must have a 'name' element."); - } - - } - - - @Override - public String formatToString() - { - return "Name:"+getName(); - } - - - } - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java index b96ddc56c6..963d019ec3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/RecovererProvider.java @@ -18,15 +18,11 @@ * under the License. * */ - package org.apache.qpid.server.configuration; -public interface VirtualHostConfig extends ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> -{ - String getName(); - - BrokerConfig getBroker(); - - String getFederationTag(); +import org.apache.qpid.server.model.ConfiguredObject; +public interface RecovererProvider +{ + ConfiguredObjectRecoverer<? extends ConfiguredObject> getRecoverer(String type); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java deleted file mode 100644 index f9e2d93cff..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java +++ /dev/null @@ -1,1031 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.TrustManagerFactory; -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.ConfigurationFactory; -import org.apache.commons.configuration.HierarchicalConfiguration; -import org.apache.commons.configuration.SystemConfiguration; -import org.apache.commons.configuration.XMLConfiguration; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.exchange.DefaultExchangeFactory; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.signal.SignalHandlerTask; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; - -import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; - -public class ServerConfiguration extends ConfigurationPlugin -{ - protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class); - - // Default Configuration values - public static final int DEFAULT_BUFFER_SIZE = 262144; - public static final String DEFAULT_STATUS_UPDATES = "on"; - public static final String SECURITY_CONFIG_RELOADED = "SECURITY CONFIGURATION RELOADED"; - - public static final int DEFAULT_FRAME_SIZE = 65536; - public static final int DEFAULT_PORT = 5672; - public static final int DEFAULT_SSL_PORT = 5671; - public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L; - public static final int DEFAULT_JMXPORT_REGISTRYSERVER = 8999; - public static final int JMXPORT_CONNECTORSERVER_OFFSET = 100; - public static final int DEFAULT_HTTP_MANAGEMENT_PORT = 8080; - public static final int DEFAULT_HTTPS_MANAGEMENT_PORT = 8443; - public static final long DEFAULT_MINIMUM_ALERT_REPEAT_GAP = 30000l; - - public static final String QPID_HOME = "QPID_HOME"; - public static final String QPID_WORK = "QPID_WORK"; - public static final String LIB_DIR = "lib"; - public static final String PLUGIN_DIR = "plugins"; - public static final String CACHE_DIR = "cache"; - - private Map<String, VirtualHostConfiguration> _virtualHosts = new HashMap<String, VirtualHostConfiguration>(); - - private File _configFile; - private File _vhostsFile; - private String _qpidWork; - private String _qpidHome; - - // Map of environment variables to config items - private static final Map<String, String> envVarMap = new HashMap<String, String>(); - - // Configuration values to be read from the configuration file - //todo Move all properties to static values to ensure system testing can be performed. - public static final String MGMT_CUSTOM_REGISTRY_SOCKET = "management.custom-registry-socket"; - public static final String MGMT_JMXPORT_REGISTRYSERVER = "management.jmxport.registryServer"; - public static final String MGMT_JMXPORT_CONNECTORSERVER = "management.jmxport.connectorServer"; - public static final String SECURITY_DEFAULT_AUTH_MANAGER = "security.default-auth-manager"; - public static final String SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER = "security.port-mappings.port-mapping.auth-manager"; - public static final String SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT = "security.port-mappings.port-mapping.port"; - public static final String STATUS_UPDATES = "status-updates"; - public static final String ADVANCED_LOCALE = "advanced.locale"; - public static final String CONNECTOR_AMQP10ENABLED = "connector.amqp10enabled"; - public static final String CONNECTOR_AMQP010ENABLED = "connector.amqp010enabled"; - public static final String CONNECTOR_AMQP091ENABLED = "connector.amqp091enabled"; - public static final String CONNECTOR_AMQP09ENABLED = "connector.amqp09enabled"; - public static final String CONNECTOR_AMQP08ENABLED = "connector.amqp08enabled"; - public static final String CONNECTOR_AMQP_SUPPORTED_REPLY = "connector.amqpDefaultSupportedProtocolReply"; - public static final String CONNECTOR_INCLUDE_10 = "connector.include10"; - public static final String CONNECTOR_INCLUDE_010 = "connector.include010"; - public static final String CONNECTOR_INCLUDE_091 = "connector.include091"; - public static final String CONNECTOR_INCLUDE_09 = "connector.include09"; - public static final String CONNECTOR_INCLUDE_08 = "connector.include08"; - - { - envVarMap.put("QPID_PORT", "connector.port"); - envVarMap.put("QPID_SSLPORT", "connector.ssl.port"); - envVarMap.put("QPID_JMXPORT_REGISTRYSERVER", MGMT_JMXPORT_REGISTRYSERVER); - envVarMap.put("QPID_JMXPORT_CONNECTORSERVER", MGMT_JMXPORT_CONNECTORSERVER); - envVarMap.put("QPID_FRAMESIZE", "advanced.framesize"); - envVarMap.put("QPID_MSGAUTH", "security.msg-auth"); - envVarMap.put("QPID_AUTOREGISTER", "auto_register"); - envVarMap.put("QPID_MANAGEMENTENABLED", "management.enabled"); - envVarMap.put("QPID_HTTPMANAGEMENTENABLED", "management.http.enabled"); - envVarMap.put("QPID_HTTPMANAGEMENTPORT", "management.http.port"); - envVarMap.put("QPID_HEARTBEATDELAY", "heartbeat.delay"); - envVarMap.put("QPID_HEARTBEATTIMEOUTFACTOR", "heartbeat.timeoutFactor"); - envVarMap.put("QPID_MAXIMUMMESSAGEAGE", "maximumMessageAge"); - envVarMap.put("QPID_MAXIMUMMESSAGECOUNT", "maximumMessageCount"); - envVarMap.put("QPID_MAXIMUMQUEUEDEPTH", "maximumQueueDepth"); - envVarMap.put("QPID_MAXIMUMMESSAGESIZE", "maximumMessageSize"); - envVarMap.put("QPID_MAXIMUMCHANNELCOUNT", "maximumChannelCount"); - envVarMap.put("QPID_MINIMUMALERTREPEATGAP", "minimumAlertRepeatGap"); - envVarMap.put("QPID_QUEUECAPACITY", "capacity"); - envVarMap.put("QPID_FLOWRESUMECAPACITY", "flowResumeCapacity"); - envVarMap.put("QPID_SOCKETRECEIVEBUFFER", "connector.socketReceiveBuffer"); - envVarMap.put("QPID_SOCKETWRITEBUFFER", "connector.socketWriteBuffer"); - envVarMap.put("QPID_TCPNODELAY", "connector.tcpNoDelay"); - envVarMap.put("QPID_STATUS-UPDATES", "status-updates"); - } - - /** - * Loads the given file and sets up the HUP signal handler. - * - * This will load the file and present the root level properties but will - * not perform any virtualhost configuration. - * <p> - * To perform this {@link #initialise()} must be called. - * <p> - * This has been made a two step process to allow the Plugin Manager and - * Configuration Manager to be initialised in the Application Registry. - * <p> - * If using this ServerConfiguration via an ApplicationRegistry there is no - * need to explicitly call {@link #initialise()} as this is done via the - * {@link ApplicationRegistry#initialise()} method. - * - * @param configurationURL - * @throws org.apache.commons.configuration.ConfigurationException - */ - public ServerConfiguration(File configurationURL) throws ConfigurationException - { - this(parseConfig(configurationURL)); - _configFile = configurationURL; - - SignalHandlerTask hupReparseTask = new SignalHandlerTask() - { - public void handle() - { - try - { - reparseConfigFileSecuritySections(); - } - catch (ConfigurationException e) - { - _logger.error("Could not reload configuration file security sections", e); - } - } - }; - - if(!hupReparseTask.register("HUP")) - { - _logger.info("Unable to register Signal HUP handler to reload security configuration."); - _logger.info("Signal HUP not supported for this OS / JVM combination - " + SignalHandlerTask.getPlatformDescription()); - } - } - - /** - * Wraps the given Commons Configuration as a ServerConfiguration. - * - * Mainly used during testing and in locations where configuration is not - * desired but the interface requires configuration. - * <p> - * If the given configuration has VirtualHost configuration then - * {@link #initialise()} must be called to perform the required setup. - * <p> - * This has been made a two step process to allow the Plugin Manager and - * Configuration Manager to be initialised in the Application Registry. - * <p> - * If using this ServerConfiguration via an ApplicationRegistry there is no - * need to explicitly call {@link #initialise()} as this is done via the - * {@link ApplicationRegistry#initialise()} method. - * - * @param conf - */ - public ServerConfiguration(Configuration conf) - { - setConfig(conf); - } - - /** - * Processes this configuration and setups any VirtualHosts defined in the - * configuration. - * - * This has been separated from the constructor to allow the PluginManager - * time to be created and provide plugins to the ConfigurationManager for - * processing here. - * <p> - * Called by {@link ApplicationRegistry#initialise()}. - * <p> - * NOTE: A DEFAULT ApplicationRegistry must exist when using this method - * or a new ApplicationRegistry will be created. - * - * @throws ConfigurationException - */ - public void initialise() throws ConfigurationException - { - setConfiguration("", getConfig()); - setupVirtualHosts(getConfig()); - } - - public String[] getElementsProcessed() - { - return new String[] { "" }; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - // Support for security.jmx.access was removed when JMX access rights were incorporated into the main ACL. - // This ensure that users remove the element from their configuration file. - - if (getListValue("security.jmx.access").size() > 0) - { - String message = "Validation error : security/jmx/access is no longer a supported element within the configuration xml." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - if (getListValue("security.jmx.principal-database").size() > 0) - { - String message = "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - if (getListValue("security.principal-databases.principal-database(0).class").size() > 0) - { - String message = "Validation error : security/principal-databases is no longer supported within the configuration xml." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - // QPID-3266. Tidy up housekeeping configuration option for scheduling frequency - if (contains("housekeeping.expiredMessageCheckPeriod")) - { - String message = "Validation error : housekeeping/expiredMessageCheckPeriod must be replaced by housekeeping/checkPeriod." - + (_configFile == null ? "" : " Configuration file : " + _configFile); - throw new ConfigurationException(message); - } - - String[] ports = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT); - String[] authManagers = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER); - if (ports.length != authManagers.length) - { - throw new ConfigurationException("Validation error: Each port-mapping must have exactly one port and exactly one auth-manager."); - } - - // QPID-3517: Inconsistency in capitalisation in the SSL configuration keys used within the connector and management configuration - // sections. For the moment, continue to understand both but generate a deprecated warning if the less preferred keystore is used. - for (String key : new String[] {"management.ssl.keystorePath", - "management.ssl.keystorePassword," + - "connector.ssl.keystorePath", - "connector.ssl.keystorePassword"}) - { - if (contains(key)) - { - final String deprecatedXpath = key.replaceAll("\\.", "/"); - final String preferredXpath = deprecatedXpath.replaceAll("keystore", "keyStore"); - _logger.warn("Validation warning: " + deprecatedXpath + " is deprecated and must be replaced by " + preferredXpath - + (_configFile == null ? "" : " Configuration file : " + _configFile)); - } - } - - // QPID-3739 certType was a misleading name. - if (contains("connector.ssl.certType")) - { - _logger.warn("Validation warning: connector/ssl/certType is deprecated and must be replaced by connector/ssl/keyManagerFactoryAlgorithm" - + (_configFile == null ? "" : " Configuration file : " + _configFile)); - } - } - - /* - * Modified to enforce virtualhosts configuration in external file or main file, but not - * both, as a fix for QPID-2360 and QPID-2361. - */ - @SuppressWarnings("unchecked") - protected void setupVirtualHosts(Configuration conf) throws ConfigurationException - { - List<String> vhostFiles = (List) conf.getList("virtualhosts"); - Configuration vhostConfig = conf.subset("virtualhosts"); - - // Only one configuration mechanism allowed - if (!vhostFiles.isEmpty() && !vhostConfig.subset("virtualhost").isEmpty()) - { - throw new ConfigurationException("Only one of external or embedded virtualhosts configuration allowed."); - } - - // We can only have one vhosts XML file included - if (vhostFiles.size() > 1) - { - throw new ConfigurationException("Only one external virtualhosts configuration file allowed, multiple filenames found."); - } - - // Virtualhost configuration object - Configuration vhostConfiguration = new HierarchicalConfiguration(); - - // Load from embedded configuration if possible - if (!vhostConfig.subset("virtualhost").isEmpty()) - { - vhostConfiguration = vhostConfig; - } - else - { - // Load from the external configuration if possible - for (String fileName : vhostFiles) - { - // Open the vhosts XML file and copy values from it to our config - _vhostsFile = new File(fileName); - if (!_vhostsFile.exists()) - { - throw new ConfigurationException("Virtualhosts file does not exist"); - } - vhostConfiguration = parseConfig(new File(fileName)); - - // save the default virtualhost name - String defaultVirtualHost = vhostConfiguration.getString("default"); - getConfig().setProperty("virtualhosts.default", defaultVirtualHost); - } - } - - // Now extract the virtual host names from the configuration object - List hosts = vhostConfiguration.getList("virtualhost.name"); - for (int j = 0; j < hosts.size(); j++) - { - String name = (String) hosts.get(j); - - // Add the virtual hosts to the server configuration - VirtualHostConfiguration virtualhost = new VirtualHostConfiguration(name, vhostConfiguration.subset("virtualhost." + name)); - _virtualHosts.put(virtualhost.getName(), virtualhost); - } - } - - private static void substituteEnvironmentVariables(Configuration conf) - { - for (Entry<String, String> var : envVarMap.entrySet()) - { - String val = System.getenv(var.getKey()); - if (val != null) - { - conf.setProperty(var.getValue(), val); - } - } - } - - private static Configuration parseConfig(File file) throws ConfigurationException - { - ConfigurationFactory factory = new ConfigurationFactory(); - factory.setConfigurationFileName(file.getAbsolutePath()); - Configuration conf = factory.getConfiguration(); - - Iterator<?> keys = conf.getKeys(); - if (!keys.hasNext()) - { - keys = null; - conf = flatConfig(file); - } - - substituteEnvironmentVariables(conf); - - return conf; - } - - /** - * Check the configuration file to see if status updates are enabled. - * - * @return true if status updates are enabled - */ - public boolean getStatusUpdatesEnabled() - { - // Retrieve the setting from configuration but default to on. - String value = getStringValue(STATUS_UPDATES, DEFAULT_STATUS_UPDATES); - - return value.equalsIgnoreCase("on"); - } - - /** - * The currently defined {@see Locale} for this broker - * - * @return the configuration defined locale - */ - public Locale getLocale() - { - String localeString = getStringValue(ADVANCED_LOCALE); - // Expecting locale of format langauge_country_variant - - // If the configuration does not have a defined locale use the JVM default - if (localeString == null) - { - return Locale.getDefault(); - } - - String[] parts = localeString.split("_"); - - Locale locale; - switch (parts.length) - { - case 1: - locale = new Locale(localeString); - break; - case 2: - locale = new Locale(parts[0], parts[1]); - break; - default: - StringBuilder variant = new StringBuilder(parts[2]); - // If we have a variant such as the Java doc suggests for Spanish - // Traditional_WIN we may end up with more than 3 parts on a - // split with '_'. So we should recombine the variant. - if (parts.length > 3) - { - for (int index = 3; index < parts.length; index++) - { - variant.append('_').append(parts[index]); - } - } - - locale = new Locale(parts[0], parts[1], variant.toString()); - } - - return locale; - } - - // Our configuration class needs to make the interpolate method - // public so it can be called below from the config method. - public static class MyConfiguration extends CompositeConfiguration - { - public String interpolate(String obj) - { - return super.interpolate(obj); - } - } - - public final static Configuration flatConfig(File file) throws ConfigurationException - { - // We have to override the interpolate methods so that - // interpolation takes place across the entirety of the - // composite configuration. Without doing this each - // configuration object only interpolates variables defined - // inside itself. - final MyConfiguration conf = new MyConfiguration(); - conf.addConfiguration(new SystemConfiguration() - { - protected String interpolate(String o) - { - return conf.interpolate(o); - } - }); - conf.addConfiguration(new XMLConfiguration(file) - { - protected String interpolate(String o) - { - return conf.interpolate(o); - } - }); - return conf; - } - - public String getConfigurationURL() - { - return _configFile == null ? "" : _configFile.getAbsolutePath(); - } - - public void reparseConfigFileSecuritySections() throws ConfigurationException - { - if (_configFile != null) - { - Configuration newConfig = parseConfig(_configFile); - setConfiguration("", newConfig); - ApplicationRegistry.getInstance().getSecurityManager().configureHostPlugins(this); - - // Reload virtualhosts from correct location - Configuration newVhosts; - if (_vhostsFile == null) - { - newVhosts = newConfig.subset("virtualhosts"); - } - else - { - newVhosts = parseConfig(_vhostsFile); - } - - VirtualHostRegistry vhostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry(); - for (String hostName : _virtualHosts.keySet()) - { - VirtualHost vhost = vhostRegistry.getVirtualHost(hostName); - Configuration vhostConfig = newVhosts.subset("virtualhost." + hostName); - vhost.getConfiguration().setConfiguration("virtualhosts.virtualhost", vhostConfig); - vhost.getSecurityManager().configureGlobalPlugins(this); - vhost.getSecurityManager().configureHostPlugins(vhost.getConfiguration()); - } - - _logger.warn(SECURITY_CONFIG_RELOADED); - } - } - - public String getQpidWork() - { - if ( _qpidWork == null ) - { - return System.getProperty(QPID_WORK, System.getProperty("java.io.tmpdir")); - } - else - { - return _qpidWork; - } - } - - public String getQpidHome() - { - if ( _qpidHome == null ) - { - return System.getProperty(QPID_HOME); - } - else - { - return _qpidHome; - } - } - - public void setJMXPortRegistryServer(int registryServerPort) - { - getConfig().setProperty(MGMT_JMXPORT_REGISTRYSERVER, registryServerPort); - } - - public int getJMXPortRegistryServer() - { - return getIntValue(MGMT_JMXPORT_REGISTRYSERVER, DEFAULT_JMXPORT_REGISTRYSERVER); - } - - public void setJMXPortConnectorServer(int connectorServerPort) - { - getConfig().setProperty(MGMT_JMXPORT_CONNECTORSERVER, connectorServerPort); - } - - public int getJMXConnectorServerPort() - { - return getIntValue(MGMT_JMXPORT_CONNECTORSERVER, getJMXPortRegistryServer() + JMXPORT_CONNECTORSERVER_OFFSET); - } - - public boolean getUseCustomRMISocketFactory() - { - return getBooleanValue(MGMT_CUSTOM_REGISTRY_SOCKET, true); - } - - public void setUseCustomRMISocketFactory(boolean bool) - { - getConfig().setProperty(MGMT_CUSTOM_REGISTRY_SOCKET, bool); - } - - public boolean getPlatformMbeanserver() - { - return getBooleanValue("management.platform-mbeanserver", true); - } - - public boolean getHTTPManagementEnabled() - { - return getBooleanValue("management.http.enabled", true); - } - - public int getHTTPManagementPort() - { - return getIntValue("management.http.port", DEFAULT_HTTP_MANAGEMENT_PORT); - } - - public boolean getHTTPSManagementEnabled() - { - return getBooleanValue("management.https.enabled", false); - } - - public int getHTTPSManagementPort() - { - return getIntValue("management.https.port", DEFAULT_HTTPS_MANAGEMENT_PORT); - } - - public String[] getVirtualHosts() - { - return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]); - } - - public String getPluginDirectory() - { - return getStringValue("plugin-directory"); - } - - public String getCacheDirectory() - { - return getStringValue("cache-directory"); - } - - public VirtualHostConfiguration getVirtualHostConfig(String name) - { - return _virtualHosts.get(name); - } - - public void setVirtualHostConfig(VirtualHostConfiguration config) - { - _virtualHosts.put(config.getName(), config); - } - - public int getFrameSize() - { - return getIntValue("advanced.framesize", DEFAULT_FRAME_SIZE); - } - - public boolean getSynchedClocks() - { - return getBooleanValue("advanced.synced-clocks"); - } - - public boolean getMsgAuth() - { - return getBooleanValue("security.msg-auth"); - } - - public String getDefaultAuthenticationManager() - { - return getStringValue(SECURITY_DEFAULT_AUTH_MANAGER); - } - - public Map<Integer, String> getPortAuthenticationMappings() - { - String[] ports = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_PORT); - String[] authManagers = getConfig().getStringArray(SECURITY_PORT_MAPPINGS_PORT_MAPPING_AUTH_MANAGER); - - Map<Integer,String> portMappings = new HashMap<Integer, String>(); - for(int i = 0; i < ports.length; i++) - { - portMappings.put(Integer.valueOf(ports[i]), authManagers[i]); - } - - return portMappings; - } - - - public String getManagementKeyStorePath() - { - final String fallback = getStringValue("management.ssl.keystorePath"); - return getStringValue("management.ssl.keyStorePath", fallback); - } - - public boolean getManagementSSLEnabled() - { - return getBooleanValue("management.ssl.enabled", false); - } - - public String getManagementKeyStorePassword() - { - final String fallback = getStringValue("management.ssl.keystorePassword"); - return getStringValue("management.ssl.keyStorePassword", fallback); - } - - public boolean getQueueAutoRegister() - { - return getBooleanValue("queue.auto_register", true); - } - - public boolean getJMXManagementEnabled() - { - return getBooleanValue("management.enabled", true); - } - - public int getHeartBeatDelay() - { - return getIntValue("heartbeat.delay", 5); - } - - public double getHeartBeatTimeout() - { - return getDoubleValue("heartbeat.timeoutFactor", 2.0); - } - - public long getMaximumMessageAge() - { - return getLongValue("maximumMessageAge"); - } - - public long getMaximumMessageCount() - { - return getLongValue("maximumMessageCount"); - } - - public long getMaximumQueueDepth() - { - return getLongValue("maximumQueueDepth"); - } - - public long getMaximumMessageSize() - { - return getLongValue("maximumMessageSize"); - } - - public long getMinimumAlertRepeatGap() - { - return getLongValue("minimumAlertRepeatGap", DEFAULT_MINIMUM_ALERT_REPEAT_GAP); - } - - public long getCapacity() - { - return getLongValue("capacity"); - } - - public long getFlowResumeCapacity() - { - return getLongValue("flowResumeCapacity", getCapacity()); - } - - public int getConnectorProcessors() - { - return getIntValue("connector.processors", 4); - } - - public List getPorts() - { - return getListValue("connector.port", Collections.<Integer>singletonList(DEFAULT_PORT)); - } - - public List getPortExclude10() - { - return getListValue("connector.non10port"); - } - - public List getPortExclude010() - { - return getListValue("connector.non010port"); - } - - public List getPortExclude091() - { - return getListValue("connector.non091port"); - } - - public List getPortExclude09() - { - return getListValue("connector.non09port"); - } - - public List getPortExclude08() - { - return getListValue("connector.non08port"); - } - - public List getPortInclude08() - { - return getListValue(CONNECTOR_INCLUDE_08); - } - - public List getPortInclude09() - { - return getListValue(CONNECTOR_INCLUDE_09); - } - - public List getPortInclude091() - { - return getListValue(CONNECTOR_INCLUDE_091); - } - - public List getPortInclude010() - { - return getListValue(CONNECTOR_INCLUDE_010); - } - - public List getPortInclude10() - { - return getListValue(CONNECTOR_INCLUDE_10); - } - - public String getBind() - { - return getStringValue("connector.bind", WILDCARD_ADDRESS); - } - - public int getReceiveBufferSize() - { - return getIntValue("connector.socketReceiveBuffer", DEFAULT_BUFFER_SIZE); - } - - public int getWriteBufferSize() - { - return getIntValue("connector.socketWriteBuffer", DEFAULT_BUFFER_SIZE); - } - - public boolean getTcpNoDelay() - { - return getBooleanValue("connector.tcpNoDelay", true); - } - - public boolean getEnableSSL() - { - return getBooleanValue("connector.ssl.enabled"); - } - - public boolean getSSLOnly() - { - return getBooleanValue("connector.ssl.sslOnly"); - } - - public List getSSLPorts() - { - return getListValue("connector.ssl.port", Collections.<Integer>singletonList(DEFAULT_SSL_PORT)); - } - - public String getConnectorKeyStorePath() - { - final String fallback = getStringValue("connector.ssl.keystorePath"); // pre-0.13 broker supported this name. - return getStringValue("connector.ssl.keyStorePath", fallback); - } - - public String getConnectorKeyStorePassword() - { - final String fallback = getStringValue("connector.ssl.keystorePassword"); // pre-0.13 brokers supported this name. - return getStringValue("connector.ssl.keyStorePassword", fallback); - } - - public String getConnectorKeyStoreType() - { - return getStringValue("connector.ssl.keyStoreType", "JKS"); - } - - public String getConnectorKeyManagerFactoryAlgorithm() - { - final String systemFallback = KeyManagerFactory.getDefaultAlgorithm(); - // deprecated, pre-0.17 brokers supported this name. - final String fallback = getStringValue("connector.ssl.certType", systemFallback); - return getStringValue("connector.ssl.keyManagerFactoryAlgorithm", fallback); - } - - public String getConnectorTrustStorePath() - { - return getStringValue("connector.ssl.trustStorePath", null); - } - - public String getConnectorTrustStorePassword() - { - return getStringValue("connector.ssl.trustStorePassword", null); - } - - public String getConnectorTrustStoreType() - { - return getStringValue("connector.ssl.trustStoreType", "JKS"); - } - - public String getConnectorTrustManagerFactoryAlgorithm() - { - return getStringValue("connector.ssl.trustManagerFactoryAlgorithm", TrustManagerFactory.getDefaultAlgorithm()); - } - - public String getCertAlias() - { - return getStringValue("connector.ssl.certAlias", null); - } - - public boolean needClientAuth() - { - return getConfig().getBoolean("connector.ssl.needClientAuth", false); - } - - public boolean wantClientAuth() - { - return getConfig().getBoolean("connector.ssl.wantClientAuth", false); - } - - public String getDefaultVirtualHost() - { - return getStringValue("virtualhosts.default"); - } - - public void setDefaultVirtualHost(String vhost) - { - getConfig().setProperty("virtualhosts.default", vhost); - } - - public void setHousekeepingCheckPeriod(long value) - { - getConfig().setProperty("housekeeping.checkPeriod", value); - } - - public long getHousekeepingCheckPeriod() - { - return getLongValue("housekeeping.checkPeriod", DEFAULT_HOUSEKEEPING_PERIOD); - } - - public long getStatisticsSamplePeriod() - { - return getConfig().getLong("statistics.sample.period", 5000L); - } - - public boolean isStatisticsGenerationBrokerEnabled() - { - return getConfig().getBoolean("statistics.generation.broker", false); - } - - public boolean isStatisticsGenerationVirtualhostsEnabled() - { - return getConfig().getBoolean("statistics.generation.virtualhosts", false); - } - - public boolean isStatisticsGenerationConnectionsEnabled() - { - return getConfig().getBoolean("statistics.generation.connections", false); - } - - public long getStatisticsReportingPeriod() - { - return getConfig().getLong("statistics.reporting.period", 0L); - } - - public boolean isStatisticsReportResetEnabled() - { - return getConfig().getBoolean("statistics.reporting.reset", false); - } - - public int getMaxChannelCount() - { - return getIntValue("maximumChannelCount", 256); - } - - /** - * List of Broker features that have been disabled within configuration. Disabled - * features won't be advertised to the clients on connection. - * - * @return list of disabled features, or empty list if no features are disabled. - */ - public List<String> getDisabledFeatures() - { - final List<String> disabledFeatures = getListValue("disabledFeatures", Collections.emptyList()); - return disabledFeatures; - } - - public boolean getManagementRightsInferAllAccess() - { - return getBooleanValue("management.managementRightsInferAllAccess", true); - } - - public int getMaxDeliveryCount() - { - return getConfig().getInt("maximumDeliveryCount", 0); - } - - /** - * Check if dead letter queue delivery is enabled, defaults to disabled if not set. - */ - public boolean isDeadLetterQueueEnabled() - { - return getConfig().getBoolean("deadLetterQueues", false); - } - - /** - * String to affix to end of queue name when generating an alternate exchange for DLQ purposes. - */ - public String getDeadLetterExchangeSuffix() - { - return getConfig().getString("deadLetterExchangeSuffix", DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); - } - - /** - * String to affix to end of queue name when generating a queue for DLQ purposes. - */ - public String getDeadLetterQueueSuffix() - { - return getConfig().getString("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); - } - - public boolean isAmqp10enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP10ENABLED, true); - } - - public boolean isAmqp010enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP010ENABLED, true); - } - - public boolean isAmqp091enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP091ENABLED, true); - } - - public boolean isAmqp09enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP09ENABLED, true); - } - - public boolean isAmqp08enabled() - { - return getConfig().getBoolean(CONNECTOR_AMQP08ENABLED, true); - } - - /** - * Returns the configured default reply to an unsupported AMQP protocol initiation, or null if there is none - */ - public AmqpProtocolVersion getDefaultSupportedProtocolReply() - { - String reply = getConfig().getString(CONNECTOR_AMQP_SUPPORTED_REPLY, null); - - return reply == null ? null : AmqpProtocolVersion.valueOf(reply); - } - - public void setQpidWork(String path) - { - _qpidWork = path; - } - - public void setQpidHome(String path) - { - _qpidHome = path; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java deleted file mode 100644 index 51dcc38c47..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration; - -import java.net.InetSocketAddress; -import org.apache.qpid.transport.NetworkTransportConfiguration; - -public class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration -{ - private final ServerConfiguration _serverConfig; - private final String _transport; - private InetSocketAddress _address; - - public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig, - final InetSocketAddress address, - final String transport) - { - _serverConfig = serverConfig; - _address = address; - _transport = transport; - } - - public Boolean getTcpNoDelay() - { - return _serverConfig.getTcpNoDelay(); - } - - public Integer getSendBufferSize() - { - return _serverConfig.getWriteBufferSize(); - } - - public Integer getReceiveBufferSize() - { - return _serverConfig.getReceiveBufferSize(); - } - - public Integer getPort() - { - return _address.getPort(); - } - - public String getHost() - { - return _address.getHostName(); - } - - public String getTransport() - { - return _transport; - } - - public Integer getConnectorProcessors() - { - return _serverConfig.getConnectorProcessors(); - } - - public InetSocketAddress getAddress() - { - return _address; - } - - public boolean needClientAuth() - { - return _serverConfig.needClientAuth(); - } - - @Override - public boolean wantClientAuth() - { - return _serverConfig.wantClientAuth(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java deleted file mode 100644 index 8fef642eff..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfig.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import org.apache.qpid.AMQException; - -public interface SessionConfig extends ConfiguredObject<SessionConfigType, SessionConfig> -{ - VirtualHostConfig getVirtualHost(); - - String getSessionName(); - - int getChannel(); - - ConnectionConfig getConnectionConfig(); - - boolean isAttached(); - - long getDetachedLifespan(); - - Long getExpiryTime(); - - Long getMaxClientRate(); - - Long getTxnStarts(); - - Long getTxnCommits(); - - Long getTxnRejects(); - - Long getTxnCount(); - - boolean isTransactional(); - - void mgmtClose() throws AMQException; -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java deleted file mode 100644 index 1685cfab60..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SessionConfigType.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class SessionConfigType extends ConfigObjectType<SessionConfigType, SessionConfig> -{ - private static final List<SessionProperty<?>> SESSION_PROPERTIES = new ArrayList<SessionProperty<?>>(); - - public static interface SessionProperty<S> extends ConfigProperty<SessionConfigType, SessionConfig, S> - { - } - - private abstract static class SessionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S> - { - public SessionReadWriteProperty(String name) - { - super(name); - SESSION_PROPERTIES.add(this); - } - } - - private abstract static class SessionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SessionConfigType, SessionConfig, S> implements SessionProperty<S> - { - public SessionReadOnlyProperty(String name) - { - super(name); - SESSION_PROPERTIES.add(this); - } - } - - public static final SessionReadOnlyProperty<VirtualHostConfig> VIRTUAL_HOST_PROPERTY = new SessionReadOnlyProperty<VirtualHostConfig>("virtualHost") - { - public VirtualHostConfig getValue(SessionConfig object) - { - return object.getVirtualHost(); - } - }; - - public static final SessionReadOnlyProperty<String> NAME_PROPERTY = new SessionReadOnlyProperty<String>("name") - { - public String getValue(SessionConfig object) - { - return object.getSessionName(); - } - }; - - public static final SessionReadOnlyProperty<Integer> CHANNEL_ID_PROPERTY = new SessionReadOnlyProperty<Integer>("channelId") - { - public Integer getValue(SessionConfig object) - { - return object.getChannel(); - } - }; - - public static final SessionReadOnlyProperty<ConnectionConfig> CONNECTION_PROPERTY = new SessionReadOnlyProperty<ConnectionConfig>("connection") - { - public ConnectionConfig getValue(SessionConfig object) - { - return object.getConnectionConfig(); - } - }; - - public static final SessionReadOnlyProperty<Boolean> ATTACHED_PROPERTY = new SessionReadOnlyProperty<Boolean>("attached") - { - public Boolean getValue(SessionConfig object) - { - return object.isAttached(); - } - }; - - public static final SessionReadOnlyProperty<Long> DETACHED_LIFESPAN_PROPERTY = new SessionReadOnlyProperty<Long>("detachedLifespan") - { - public Long getValue(SessionConfig object) - { - return object.getDetachedLifespan(); - } - }; - - public static final SessionReadOnlyProperty<Long> EXPIRE_TIME_PROPERTY = new SessionReadOnlyProperty<Long>("expireTime") - { - public Long getValue(SessionConfig object) - { - return object.getExpiryTime(); - } - }; - - public static final SessionReadOnlyProperty<Long> MAX_CLIENT_RATE_PROPERTY = new SessionReadOnlyProperty<Long>("maxClientRate") - { - public Long getValue(SessionConfig object) - { - return object.getMaxClientRate(); - } - }; - - private static final SessionConfigType INSTANCE = new SessionConfigType(); - - private SessionConfigType() - { - } - - public Collection<SessionProperty<?>> getProperties() - { - return Collections.unmodifiableList(SESSION_PROPERTIES); - } - - public static SessionConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java deleted file mode 100644 index 7b7848dd87..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfigType.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public final class SubscriptionConfigType extends ConfigObjectType<SubscriptionConfigType, SubscriptionConfig> -{ - private static final List<SubscriptionProperty<?>> SUBSCRIPTION_PROPERTIES = new ArrayList<SubscriptionProperty<?>>(); - - public static interface SubscriptionProperty<S> extends ConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> - { - } - - private abstract static class SubscriptionReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S> - { - public SubscriptionReadWriteProperty(String name) - { - super(name); - SUBSCRIPTION_PROPERTIES.add(this); - } - } - - private abstract static class SubscriptionReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SubscriptionConfigType, SubscriptionConfig, S> implements SubscriptionProperty<S> - { - public SubscriptionReadOnlyProperty(String name) - { - super(name); - SUBSCRIPTION_PROPERTIES.add(this); - } - } - - public static final SubscriptionReadOnlyProperty<SessionConfig> SESSION_PROPERTY = new SubscriptionReadOnlyProperty<SessionConfig>("session") - { - public SessionConfig getValue(SubscriptionConfig object) - { - return object.getSessionConfig(); - } - }; - - public static final SubscriptionReadOnlyProperty<QueueConfig> QUEUE_PROPERTY = new SubscriptionReadOnlyProperty<QueueConfig>("queue") - { - public QueueConfig getValue(SubscriptionConfig object) - { - return object.getQueue(); - } - }; - - public static final SubscriptionReadOnlyProperty<String> NAME_PROPERTY = new SubscriptionReadOnlyProperty<String>("name") - { - public String getValue(SubscriptionConfig object) - { - return object.getName(); - } - }; - - public static final SubscriptionReadOnlyProperty<Map<String,Object>> ARGUMENTS = new SubscriptionReadOnlyProperty<Map<String,Object>>("arguments") - { - public Map<String,Object> getValue(SubscriptionConfig object) - { - return object.getArguments(); - } - }; - - public static final SubscriptionReadOnlyProperty<String> CREDIT_MODE_PROPERTY = new SubscriptionReadOnlyProperty<String>("creditMode") - { - public String getValue(SubscriptionConfig object) - { - return object.getCreditMode(); - } - }; - - public static final SubscriptionReadOnlyProperty<Boolean> BROWSING_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("browsing") - { - public Boolean getValue(SubscriptionConfig object) - { - return object.isBrowsing(); - } - }; - - public static final SubscriptionReadOnlyProperty<Boolean> EXCLUSIVE_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("exclusive") - { - public Boolean getValue(SubscriptionConfig object) - { - return object.isExclusive(); - } - }; - - public static final SubscriptionReadOnlyProperty<Boolean> EXPLICIT_ACK_PROPERTY = new SubscriptionReadOnlyProperty<Boolean>("explicitAck") - { - public Boolean getValue(SubscriptionConfig object) - { - return object.isExplicitAcknowledge(); - } - }; - - private static final SubscriptionConfigType INSTANCE = new SubscriptionConfigType(); - - private SubscriptionConfigType() - { - } - - public Collection<SubscriptionProperty<?>> getProperties() - { - return Collections.unmodifiableList(SUBSCRIPTION_PROPERTIES); - } - - - public static SubscriptionConfigType getInstance() - { - return INSTANCE; - } - - - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java deleted file mode 100644 index 80c2e8b2f1..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public class SystemConfigImpl implements SystemConfig -{ - private static final String OS_NAME = System.getProperty("os.name"); - private static final String OS_ARCH = System.getProperty("os.arch"); - private static final String OS_VERSION = System.getProperty("os.version"); - - private final UUID _qmfId; - private String _name; - - private final String _host; - - private final Map<UUID, BrokerConfig> _brokers = new ConcurrentHashMap<UUID, BrokerConfig>(); - - private final long _createTime = System.currentTimeMillis(); - private final ConfigStore _store; - - public SystemConfigImpl(ConfigStore store) - { - this(store.createId(), store); - } - - public SystemConfigImpl(UUID qmfId, ConfigStore store) - { - _qmfId = qmfId; - _store = store; - String host; - try - { - InetAddress addr = InetAddress.getLocalHost(); - host = addr.getHostName(); - } - catch (UnknownHostException e) - { - host="localhost"; - } - _host = host; - } - - public String getName() - { - return _name; - } - - public String getOperatingSystemName() - { - return OS_NAME; - } - - public String getNodeName() - { - return _host; - } - - public String getOSRelease() - { - return OS_VERSION; - } - - public String getOSVersion() - { - return ""; - } - - public String getOSArchitecture() - { - return OS_ARCH; - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public SystemConfigType getConfigType() - { - return SystemConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return null; - } - - public boolean isDurable() - { - return false; - } - - public void addBroker(final BrokerConfig broker) - { - broker.setSystem(this); - _store.addConfiguredObject(broker); - _brokers.put(broker.getQMFId(), broker); - } - - public void removeBroker(final BrokerConfig broker) - { - _brokers.remove(broker.getQMFId()); - _store.removeConfiguredObject(broker); - } - - public long getCreateTime() - { - return _createTime; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java deleted file mode 100644 index 4a383cce7a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfigType.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -public final class SystemConfigType extends ConfigObjectType<SystemConfigType, SystemConfig> -{ - private static final List<SystemProperty<?>> SYSTEM_PROPERTIES = new ArrayList<SystemProperty<?>>(); - - public static interface SystemProperty<S> extends ConfigProperty<SystemConfigType, SystemConfig, S> - { - } - - private abstract static class SystemReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S> - { - public SystemReadWriteProperty(String name) - { - super(name); - SYSTEM_PROPERTIES.add(this); - } - } - - private abstract static class SystemReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<SystemConfigType, SystemConfig, S> implements SystemProperty<S> - { - public SystemReadOnlyProperty(String name) - { - super(name); - SYSTEM_PROPERTIES.add(this); - } - } - - public static final SystemReadOnlyProperty<String> NAME_PROPERTY = new SystemReadOnlyProperty<String>("name") - { - public String getValue(SystemConfig object) - { - return object.getName(); - } - }; - - public static final SystemReadOnlyProperty<UUID> ID_PROPERTY = new SystemReadOnlyProperty<UUID>("id") - { - public UUID getValue(SystemConfig object) - { - return object.getQMFId(); - } - }; - - public static final SystemReadOnlyProperty<String> OS_NAME_PROPERTY = new SystemReadOnlyProperty<String>("osName") - { - public String getValue(SystemConfig object) - { - return object.getOperatingSystemName(); - } - }; - - public static final SystemReadOnlyProperty<String> NODE_NAME_PROPERTY = new SystemReadOnlyProperty<String>("nodeName") - { - public String getValue(SystemConfig object) - { - return object.getNodeName(); - } - }; - - public static final SystemReadOnlyProperty<String> RELEASE_PROPERTY = new SystemReadOnlyProperty<String>("release") - { - public String getValue(SystemConfig object) - { - return object.getOSRelease(); - } - }; - - public static final SystemReadOnlyProperty<String> VERSION_PROPERTY = new SystemReadOnlyProperty<String>("version") - { - public String getValue(SystemConfig object) - { - return object.getOSVersion(); - } - }; - - public static final SystemReadOnlyProperty<String> MACHINE_PROPERTY = new SystemReadOnlyProperty<String>("machine") - { - public String getValue(SystemConfig object) - { - return object.getOSArchitecture(); - } - }; - - private static final SystemConfigType INSTANCE = new SystemConfigType(); - - private SystemConfigType() - { - } - - public Collection<SystemProperty<?>> getProperties() - { - return Collections.unmodifiableList(SYSTEM_PROPERTIES); - } - - - - public static SystemConfigType getInstance() - { - return INSTANCE; - } - - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java deleted file mode 100644 index aaa1766489..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfig.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; - -public class TopicConfig extends ConfigurationPlugin -{ - public TopicConfig() - { - setConfig(new PropertiesConfiguration()); - } - - @Override - public String[] getElementsProcessed() - { - return new String[]{"name", "subscriptionName"}; - } - - public String getName() - { - // If we don't have a specific topic then this config is for all topics. - return getStringValue("name", "#"); - } - - public String getSubscriptionName() - { - return getStringValue("subscriptionName"); - } - - public void validateConfiguration() throws ConfigurationException - { - if (getConfig().isEmpty()) - { - throw new ConfigurationException("Topic section cannot be empty."); - } - - if (getStringValue("name") == null && getSubscriptionName() == null) - { - throw new ConfigurationException("Topic section must have a 'name' or 'subscriptionName' element."); - } - - } - - - @Override - public String formatToString() - { - String response = "Topic:"+getName(); - if (getSubscriptionName() != null) - { - response += ", SubscriptionName:"+getSubscriptionName(); - } - - return response; - } -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java deleted file mode 100644 index feafd3de1d..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/TopicConfiguration.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.queue.AMQQueue; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class TopicConfiguration extends ConfigurationPlugin implements ExchangeConfigurationPlugin -{ - public static final ConfigurationPluginFactory FACTORY = new TopicConfigurationFactory(); - - private static final String VIRTUALHOSTS_VIRTUALHOST_TOPICS = "virtualhosts.virtualhost.topics"; - - public static class TopicConfigurationFactory implements ConfigurationPluginFactory - { - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - TopicConfiguration topicsConfig = new TopicConfiguration(); - topicsConfig.setConfiguration(path, config); - return topicsConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList(VIRTUALHOSTS_VIRTUALHOST_TOPICS); - } - } - - private Map<String, TopicConfig> _topics = new HashMap<String, TopicConfig>(); - private Map<String, Map<String, TopicConfig>> _subscriptions = new HashMap<String, Map<String, TopicConfig>>(); - - public String[] getElementsProcessed() - { - return new String[]{"topic"}; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - if (getConfig().isEmpty()) - { - throw new ConfigurationException("Topics section cannot be empty."); - } - - int topics = getConfig().getList("topic.name").size() + - getConfig().getList("topic.subscriptionName").size(); - - for (int index = 0; index < topics; index++) - { - Configuration topicSubset = getConfig().subset("topic(" + index + ")"); - - // This will occur when we have a subscriptionName that is bound to a - // topic. - if (topicSubset.isEmpty()) - { - break; - } - - TopicConfig topic = new TopicConfig(); - - topic.setConfiguration(VIRTUALHOSTS_VIRTUALHOST_TOPICS + ".topic", topicSubset ); - - String name = getConfig().getString("topic(" + index + ").name"); - String subscriptionName = getConfig().getString("topic(" + index + ").subscriptionName"); - - // Record config if subscriptionName is there - if (subscriptionName != null) - { - processSubscription(subscriptionName, topic); - } - else - { - // Otherwise record config as topic if we have the name - if (name != null) - { - processTopic(name, topic); - } - } - } - } - - /** - * @param name - * @param topic - * - * @throws org.apache.commons.configuration.ConfigurationException - * - */ - private void processTopic(String name, TopicConfig topic) throws ConfigurationException - { - if (_topics.containsKey(name)) - { - throw new ConfigurationException("Topics section cannot contain two entries for the same topic."); - } - else - { - _topics.put(name, topic); - } - } - - - private void processSubscription(String name, TopicConfig topic) throws ConfigurationException - { - Map<String,TopicConfig> topics; - if (_subscriptions.containsKey(name)) - { - topics = _subscriptions.get(name); - - if (topics.containsKey(topic.getName())) - { - throw new ConfigurationException("Subcription cannot contain two entries for the same topic."); - } - } - else - { - topics = new HashMap<String,TopicConfig>(); - } - - topics.put(topic.getName(),topic); - _subscriptions.put(name, topics); - - } - - @Override - public String formatToString() - { - return "Topics:" + _topics + ", Subscriptions:" + _subscriptions; - } - - /** - * This processes the given queue and apply configuration in the following - * order: - * - * Global Topic Values -> Topic Values -> Subscription Values - * - * @param queue - * - * @return - */ - public ConfigurationPlugin getConfiguration(AMQQueue queue) - { - //Create config with global topic configuration - TopicConfig config = new TopicConfig(); - - // Add global topic configuration - config.addConfiguration(this); - - // Process Topic Bindings as these are more generic than subscriptions - List<TopicConfig> boundToTopics = new LinkedList<TopicConfig>(); - - //Merge the configuration in the order that they are bound - for (Binding binding : queue.getBindings()) - { - if (binding.getExchange().getType().equals(TopicExchange.TYPE)) - { - // Identify topic for the binding key - TopicConfig topicConfig = getTopicConfigForRoutingKey(binding.getBindingKey()); - if (topicConfig != null) - { - boundToTopics.add(topicConfig); - } - } - } - - // If the Queue is bound to a number of topics then only use the global - // topic configuration. - // todo - What does it mean in terms of configuration to be bound to a - // number of topics? Do we try and merge? - // YES - right thing to do would be to merge from generic to specific. - // Means we need to be able to get an ordered list of topics for this - // binding. - if (boundToTopics.size() == 1) - { - config.addConfiguration(boundToTopics.get(0)); - } - - // If we have a subscription then attempt to look it up. - String subscriptionName = queue.getName(); - - // Apply subscription configurations - if (_subscriptions.containsKey(subscriptionName)) - { - - //Get all the Configuration that this subscription is bound to. - Map<String, TopicConfig> topics = _subscriptions.get(subscriptionName); - - TopicConfig subscriptionSpecificConfig = null; - - // See if we have a TopicConfig in topics for a topic we are bound to. - for (Binding binding : queue.getBindings()) - { - if (binding.getExchange().getType().equals(TopicExchange.TYPE)) - { - //todo - What does it mean to have multiple matches? - // Take the first match we get - if (subscriptionSpecificConfig == null) - { - // lookup the binding to see if we have a match in the subscription configs - subscriptionSpecificConfig = topics.get(binding.getBindingKey()); - } - } - } - - //todo we don't account for wild cards here. only explicit matching and all subscriptions - if (subscriptionSpecificConfig == null) - { - // lookup the binding to see if we have a match in the subscription configs - subscriptionSpecificConfig = topics.get("#"); - } - - // Apply subscription specific config. - if (subscriptionSpecificConfig != null) - { - config.addConfiguration(subscriptionSpecificConfig); - } - } - return config; - } - - /** - * This method should perform the same heuristics as the TopicExchange - * to attempt to identify a piece of configuration for the give routingKey. - * - * i.e. If we have 'stocks.*' defined in the config - * and we bind 'stocks.appl' then we should return the 'stocks.*' - * configuration. - * - * @param routingkey the key to lookup - * - * @return the TopicConfig if found. - */ - private TopicConfig getTopicConfigForRoutingKey(String routingkey) - { - //todo actually perform TopicExchange style lookup not just straight - // lookup as we are just now. - return _topics.get(routingkey); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java deleted file mode 100644 index 16e08e3934..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfigType.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.configuration; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public class VirtualHostConfigType extends ConfigObjectType<VirtualHostConfigType, VirtualHostConfig> -{ - private static final List<VirtualHostProperty<?>> VIRTUAL_HOST_PROPERTIES = new ArrayList<VirtualHostProperty<?>>(); - private static final VirtualHostConfigType INSTANCE = new VirtualHostConfigType(); -public static interface VirtualHostProperty<S> extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> - { - } - - private abstract static class VirtualHostReadWriteProperty<S> extends ConfigProperty.ReadWriteConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S> - { - public VirtualHostReadWriteProperty(String name) - { - super(name); - VIRTUAL_HOST_PROPERTIES.add(this); - } - } - - private abstract static class VirtualHostReadOnlyProperty<S> extends ConfigProperty.ReadOnlyConfigProperty<VirtualHostConfigType, VirtualHostConfig, S> implements VirtualHostProperty<S> - { - public VirtualHostReadOnlyProperty(String name) - { - super(name); - VIRTUAL_HOST_PROPERTIES.add(this); - } - } - - - public static final VirtualHostReadOnlyProperty<String> NAME_PROPERTY = new VirtualHostReadOnlyProperty<String>("name") - { - public String getValue(VirtualHostConfig object) - { - return object.getName(); - } - }; - - - public static final VirtualHostReadOnlyProperty<BrokerConfig> BROKER_PROPERTY = new VirtualHostReadOnlyProperty<BrokerConfig>("broker") - { - public BrokerConfig getValue(VirtualHostConfig object) - { - return object.getBroker(); - } - }; - - public static final VirtualHostReadOnlyProperty<String> FEDERATION_TAG_PROPERTY = new VirtualHostReadOnlyProperty<String>("federationTag") - { - public String getValue(VirtualHostConfig object) - { - return object.getFederationTag(); - } - }; - - - - public Collection<? extends ConfigProperty<VirtualHostConfigType, VirtualHostConfig, ?>> getProperties() - { - return Collections.unmodifiableList(VIRTUAL_HOST_PROPERTIES); - } - - - private VirtualHostConfigType() - { - } - - public static VirtualHostConfigType getInstance() - { - return INSTANCE; - } - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java index e557085631..eada676b65 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java @@ -23,35 +23,66 @@ package org.apache.qpid.server.configuration; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; - -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.registry.ApplicationRegistry; + +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.store.MemoryMessageStore; -import java.util.ArrayList; -import java.util.Arrays; +import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -public class VirtualHostConfiguration extends ConfigurationPlugin +public class VirtualHostConfiguration extends AbstractConfiguration { private final String _name; private final Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>(); private final Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>(); + private final Broker _broker; + private final long _defaultHouseKeepingCheckPeriod; - public VirtualHostConfiguration(String name, Configuration config) throws ConfigurationException + public VirtualHostConfiguration(String name, Configuration config, Broker broker) throws ConfigurationException { _name = name; + _broker = broker; + + // store value of this attribute for running life of virtual host since updating of this value has no run-time effect + _defaultHouseKeepingCheckPeriod = ((Number)_broker.getAttribute(Broker.HOUSEKEEPING_CHECK_PERIOD)).longValue(); setConfiguration(config); } + public VirtualHostConfiguration(String name, File configurationFile, Broker broker) throws ConfigurationException + { + this(name, loadConfiguration(name, configurationFile), broker); + } + + private static Configuration loadConfiguration(String name, File configurationFile) throws ConfigurationException + { + Configuration configuration = null; + if (configurationFile == null) + { + throw new IllegalConfigurationException("Virtualhost configuration file must be supplied!"); + } + else + { + Configuration virtualHostConfig = XmlConfigurationUtilities.parseConfig(configurationFile, null); + + // check if it is an old virtual host configuration file which has an element of the same name as virtual host + Configuration config = virtualHostConfig.subset("virtualhost." + XmlConfigurationUtilities.escapeTagName(name)); + if (config.isEmpty()) + { + // assume it is a new configuration which does not have an element of the same name as the virtual host + configuration = virtualHostConfig; + } + else + { + configuration = config; + } + } + return configuration; + } + /** * Apply the given configuration to this VirtualHostConfiguration * @@ -89,12 +120,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin public long getHousekeepingCheckPeriod() { - return getLongValue("housekeeping.checkPeriod", ApplicationRegistry.getInstance().getConfiguration().getHousekeepingCheckPeriod()); - } - - public List getCustomExchanges() - { - return getListValue("custom-exchanges.class-name"); + return getLongValue("housekeeping.checkPeriod", _defaultHouseKeepingCheckPeriod); } public Configuration getStoreConfiguration() @@ -149,138 +175,39 @@ public class VirtualHostConfiguration extends ConfigurationPlugin } } - public ConfigurationPlugin getQueueConfiguration(AMQQueue queue) - { - VirtualHostConfiguration hostConfig = queue.getVirtualHost().getConfiguration(); - - // First check if we have a named queue configuration (the easy case) - if (Arrays.asList(hostConfig.getQueueNames()).contains(queue.getName())) - { - return null; - } - - // We don't have an explicit queue config we must find out what we need. - ArrayList<Binding> bindings = new ArrayList<Binding>(queue.getBindings()); - - List<AMQShortString> exchangeClasses = new ArrayList<AMQShortString>(bindings.size()); - - //Remove default exchange - for (int index = 0; index < bindings.size(); index++) - { - // Ignore the DEFAULT Exchange binding - if (bindings.get(index).getExchange().getNameShortString().equals(ExchangeDefaults.DEFAULT_EXCHANGE_NAME)) - { - bindings.remove(index); - } - else - { - exchangeClasses.add(bindings.get(index).getExchange().getType().getName()); - - if (exchangeClasses.size() > 1) - { - // If we have more than 1 class of exchange then we can only use the global queue configuration. - // and this will be returned from the default getQueueConfiguration - return null; - } - } - } - - // If we are just bound the the default exchange then use the default. - if (bindings.isEmpty()) - { - return null; - } - - // If we are bound to only one type of exchange then we are going - // to have to resolve the configuration for that exchange. - - String exchangeName = bindings.get(0).getExchange().getType().getName().toString(); - - // Lookup a Configuration handler for this Exchange. - - // Build the expected class name. <Exchangename>sConfiguration - // i.e. TopicConfiguration or HeadersConfiguration - String exchangeClass = "org.apache.qpid.server.configuration." - + exchangeName.substring(0, 1).toUpperCase() - + exchangeName.substring(1) + "Configuration"; - - ExchangeConfigurationPlugin exchangeConfiguration - = (ExchangeConfigurationPlugin) queue.getVirtualHost().getConfiguration().getConfiguration(exchangeClass); - - // now need to perform the queue-topic-topics-queues magic. - // So make a new ConfigurationObject that will hold all the configuration for this queue. - ConfigurationPlugin queueConfig = new QueueConfiguration.QueueConfig(); - - // Initialise the queue with any Global values we may have - PropertiesConfiguration newQueueConfig = new PropertiesConfiguration(); - newQueueConfig.setProperty("name", queue.getName()); - - try - { - //Set the queue name - CompositeConfiguration mungedConf = new CompositeConfiguration(); - //Set the queue name - mungedConf.addConfiguration(newQueueConfig); - //Set the global queue configuration - mungedConf.addConfiguration(getConfig().subset("queues")); - - // Set configuration - queueConfig.setConfiguration("virtualhosts.virtualhost.queues", mungedConf); - } - catch (ConfigurationException e) - { - // This will not occur as queues only require a name. - _logger.error("QueueConfiguration requirements have changed."); - } - - // Merge any configuration the Exchange wishes to apply - if (exchangeConfiguration != null) - { - queueConfig.addConfiguration(exchangeConfiguration.getConfiguration(queue)); - } - - //Finally merge in any specific queue configuration we have. - if (_queues.containsKey(queue.getName())) - { - queueConfig.addConfiguration(_queues.get(queue.getName())); - } - - return queueConfig; - } - public int getMaximumMessageAge() { - return getIntValue("queues.maximumMessageAge"); + return getIntValue("queues.maximumMessageAge", getBrokerAttributeAsInt(Broker.ALERT_THRESHOLD_MESSAGE_AGE)); } public Long getMaximumQueueDepth() { - return getLongValue("queues.maximumQueueDepth"); + return getLongValue("queues.maximumQueueDepth", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_QUEUE_DEPTH)); } public Long getMaximumMessageSize() { - return getLongValue("queues.maximumMessageSize"); + return getLongValue("queues.maximumMessageSize", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_MESSAGE_SIZE)); } public Long getMaximumMessageCount() { - return getLongValue("queues.maximumMessageCount"); + return getLongValue("queues.maximumMessageCount", getBrokerAttributeAsLong(Broker.ALERT_THRESHOLD_MESSAGE_COUNT)); } public Long getMinimumAlertRepeatGap() { - return getLongValue("queues.minimumAlertRepeatGap", ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap()); + return getLongValue("queues.minimumAlertRepeatGap", getBrokerAttributeAsLong(Broker.ALERT_REPEAT_GAP)); } public long getCapacity() { - return getLongValue("queues.capacity"); + return getLongValue("queues.capacity", getBrokerAttributeAsLong(Broker.FLOW_CONTROL_SIZE_BYTES)); } public long getFlowResumeCapacity() { - return getLongValue("queues.flowResumeCapacity", getCapacity()); + return getLongValue("queues.flowResumeCapacity", getBrokerAttributeAsLong(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES)); } public String[] getElementsProcessed() @@ -336,7 +263,7 @@ public class VirtualHostConfiguration extends ConfigurationPlugin public int getMaxDeliveryCount() { - return getIntValue("queues.maximumDeliveryCount", ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount()); + return getIntValue("queues.maximumDeliveryCount", getBrokerAttributeAsInt(Broker.MAXIMUM_DELIVERY_ATTEMPTS)); } /** @@ -344,7 +271,25 @@ public class VirtualHostConfiguration extends ConfigurationPlugin */ public boolean isDeadLetterQueueEnabled() { - return getBooleanValue("queues.deadLetterQueues", ApplicationRegistry.getInstance().getConfiguration().isDeadLetterQueueEnabled()); + return getBooleanValue("queues.deadLetterQueues", getBrokerAttributeAsBoolean(Broker.DEAD_LETTER_QUEUE_ENABLED)); + } + + private long getBrokerAttributeAsLong(String name) + { + Number brokerValue = (Number)_broker.getAttribute(name); + return brokerValue == null? 0 : brokerValue.longValue(); + } + + private int getBrokerAttributeAsInt(String name) + { + Number brokerValue = (Number)_broker.getAttribute(name); + return brokerValue == null? 0 : brokerValue.intValue(); + } + + private boolean getBrokerAttributeAsBoolean(String name) + { + Boolean brokerValue = (Boolean)_broker.getAttribute(name); + return brokerValue == null? false : brokerValue.booleanValue(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java new file mode 100644 index 0000000000..c0cff2c109 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/XmlConfigurationUtilities.java @@ -0,0 +1,111 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration; + +import java.io.File; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.ConfigurationFactory; +import org.apache.commons.configuration.SystemConfiguration; +import org.apache.commons.configuration.XMLConfiguration; + +public class XmlConfigurationUtilities +{ + + // Our configuration class needs to make the interpolate method + // public so it can be called below from the config method. + public static class MyConfiguration extends CompositeConfiguration + { + public String interpolate(String obj) + { + return super.interpolate(obj); + } + } + + public static Configuration parseConfig(File file, Map<String, String> envVarMap) throws ConfigurationException + { + ConfigurationFactory factory = new ConfigurationFactory(); + factory.setConfigurationFileName(file.getAbsolutePath()); + Configuration conf = factory.getConfiguration(); + + Iterator<?> keys = conf.getKeys(); + if (!keys.hasNext()) + { + keys = null; + conf = flatConfig(file); + } + + XmlConfigurationUtilities.substituteEnvironmentVariables(conf, envVarMap); + return conf; + } + + public final static Configuration flatConfig(File file) throws ConfigurationException + { + // We have to override the interpolate methods so that + // interpolation takes place across the entirety of the + // composite configuration. Without doing this each + // configuration object only interpolates variables defined + // inside itself. + final MyConfiguration conf = new MyConfiguration(); + conf.addConfiguration(new SystemConfiguration() + { + protected String interpolate(String o) + { + return conf.interpolate(o); + } + }); + conf.addConfiguration(new XMLConfiguration(file) + { + protected String interpolate(String o) + { + return conf.interpolate(o); + } + }); + return conf; + } + + static void substituteEnvironmentVariables(Configuration conf, Map<String, String> envVarMap) + { + if (envVarMap == null || envVarMap.isEmpty()) + { + return; + } + for (Entry<String, String> var : envVarMap.entrySet()) + { + String val = System.getenv(var.getKey()); + if (val != null) + { + conf.setProperty(var.getValue(), val); + } + } + } + + + public static String escapeTagName(String name) + { + return name.replaceAll("\\.", "\\.\\."); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java index d08e3bc806..3c17faef75 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/AbstractConfiguration.java @@ -23,25 +23,16 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConversionException; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.ConfigurationManager; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; - import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; -public abstract class ConfigurationPlugin +public abstract class AbstractConfiguration { - protected static final Logger _logger = Logger.getLogger(ConfigurationPlugin.class); - - private Map<String, ConfigurationPlugin> - _pluginConfiguration = new HashMap<String, ConfigurationPlugin>(); + protected static final Logger _logger = Logger.getLogger(AbstractConfiguration.class); private Configuration _config; @@ -69,11 +60,6 @@ public abstract class ConfigurationPlugin return _config; } - public <C extends ConfigurationPlugin> C getConfiguration(String plugin) - { - return (C) _pluginConfiguration.get(plugin); - } - /** * Sets the configuration for this plugin * @@ -118,7 +104,7 @@ public abstract class ConfigurationPlugin // With an XMLConfiguration the key will be [@property] // but with a CompositeConfiguration it will be @property]. // Hide this issue from our users so when/if we change the - // configuration they don't have to. + // configuration they don't have to. int bracketIndex = tag.indexOf("["); if (bracketIndex != -1) { @@ -140,62 +126,9 @@ public abstract class ConfigurationPlugin } } - offerRemainingConfigurationToOtherPlugins(path, configuration, elements); - validateConfiguration(); } - private void offerRemainingConfigurationToOtherPlugins(String path, - Configuration configuration, Set<String> elements) throws ConfigurationException - { - final IApplicationRegistry appRegistry = safeGetApplicationRegistryInstance(); - - if (appRegistry == null) - { - // We see this happen during shutdown due to asynchronous reconfig using IO threads. - // Need to remove the responsibility for offering configuration to other class. - _logger.info("Cannot offer remaining config to other plugins, can't find app registry"); - return; - } - - final ConfigurationManager configurationManager = appRegistry.getConfigurationManager(); - // Process the elements in the configuration - for (String element : elements) - { - Configuration handled = element.length() == 0 ? configuration : configuration.subset(element); - - String configurationElement = element; - if (path.length() > 0) - { - configurationElement = path + "." + configurationElement; - } - - List<ConfigurationPlugin> handlers = configurationManager.getConfigurationPlugins(configurationElement, handled); - - if(_logger.isDebugEnabled()) - { - _logger.debug("For '" + element + "' found handlers (" + handlers.size() + "):" + handlers); - } - - for (ConfigurationPlugin plugin : handlers) - { - _pluginConfiguration.put(plugin.getClass().getName(), plugin); - } - } - } - - private IApplicationRegistry safeGetApplicationRegistryInstance() - { - try - { - return ApplicationRegistry.getInstance(); - } - catch (IllegalStateException ise) - { - return null; - } - } - /** Helper method to print out list of keys in a {@link Configuration}. */ public static final void showKeys(Configuration config) { @@ -382,101 +315,9 @@ public abstract class ConfigurationPlugin } } - /** - * Given another configuration merge the configuration into our own config - * - * The new values being merged in will take precedence over existing values. - * - * In the simplistic case this means something like: - * - * So if we have configuration set - * name = 'fooo' - * - * And the new configuration contains a name then that will be reset. - * name = 'new' - * - * However this plugin will simply contain other plugins so the merge will - * be called until we end up at a base plugin that understand how to merge - * items. i.e Alerting values. Where the provided configuration will take - * precedence. - * - * @param configuration the config to merge in to our own. - */ - public void addConfiguration(ConfigurationPlugin configuration) - { - // If given configuration is null then there is nothing to process. - if (configuration == null) - { - return; - } - - // Merge all the sub configuration items - for (Map.Entry<String, ConfigurationPlugin> newPlugins : configuration._pluginConfiguration.entrySet()) - { - String key = newPlugins.getKey(); - ConfigurationPlugin config = newPlugins.getValue(); - - if (_pluginConfiguration.containsKey(key)) - { - //Merge the configuration if we already have this type of config - _pluginConfiguration.get(key).mergeConfiguration(config); - } - else - { - //otherwise just add it to our config. - _pluginConfiguration.put(key, config); - } - } - - //Merge the configuration itself - String key = configuration.getClass().getName(); - if (_pluginConfiguration.containsKey(key)) - { - //Merge the configuration if we already have this type of config - _pluginConfiguration.get(key).mergeConfiguration(configuration); - } - else - { - //If we are adding a configuration of our own type then merge - if (configuration.getClass() == this.getClass()) - { - mergeConfiguration(configuration); - } - else - { - // just store this in case someone else needs it. - _pluginConfiguration.put(key, configuration); - } - - } - - } - - protected void mergeConfiguration(ConfigurationPlugin configuration) - { - _config = configuration.getConfig(); - } - - public String toString() - { - StringBuilder sb = new StringBuilder(); - - sb.append("\n").append(getClass().getSimpleName()); - sb.append("=[ (").append(formatToString()).append(")"); - - for(Map.Entry<String,ConfigurationPlugin> item : _pluginConfiguration.entrySet()) - { - sb.append("\n").append(item.getValue()); - } - - sb.append("]\n"); - - return sb.toString(); - } - - public String formatToString() + public static String escapeTagName(String name) { - return super.toString(); + return name.replaceAll("\\.", "\\.\\."); } protected void setConfig(Configuration config) diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java deleted file mode 100644 index fa41f3ef06..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPluginFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import java.util.List; - -public interface ConfigurationPluginFactory -{ - /** - * The Parent paths of the configuration that this plugin supports. - * - * For example, {@code queue} elements have a parent path of {@code virtualhosts.virtualhost}. - */ - public List<String> getParentPaths(); - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException; -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java deleted file mode 100644 index a90b1d514f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionConfiguration.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeUnit; - -public class SlowConsumerDetectionConfiguration extends ConfigurationPlugin -{ - public static class SlowConsumerDetectionConfigurationFactory implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - SlowConsumerDetectionConfiguration slowConsumerConfig = new SlowConsumerDetectionConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList("virtualhosts.virtualhost.slow-consumer-detection"); - } - } - - //Set Default time unit to seconds - private TimeUnit _timeUnit = TimeUnit.SECONDS; - - public String[] getElementsProcessed() - { - return new String[]{"delay", - "timeunit"}; - } - - public long getDelay() - { - return getLongValue("delay", 10); - } - - public TimeUnit getTimeUnit() - { - return _timeUnit; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - validatePositiveLong("delay"); - - String timeUnit = getStringValue("timeunit"); - - if (timeUnit != null) - { - try - { - _timeUnit = TimeUnit.valueOf(timeUnit.toUpperCase()); - } - catch (IllegalArgumentException iae) - { - throw new ConfigurationException("Unable to configure Slow Consumer Detection invalid TimeUnit:" + timeUnit); - } - } - - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java deleted file mode 100644 index a9026c6164..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionPolicyConfiguration.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import java.util.Arrays; -import java.util.List; - -public class SlowConsumerDetectionPolicyConfiguration extends ConfigurationPlugin -{ - public static class SlowConsumerDetectionPolicyConfigurationFactory implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - SlowConsumerDetectionPolicyConfiguration slowConsumerConfig = new SlowConsumerDetectionPolicyConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList( - "virtualhosts.virtualhost.queues.slow-consumer-detection.policy", - "virtualhosts.virtualhost.queues.queue.slow-consumer-detection.policy", - "virtualhosts.virtualhost.topics.slow-consumer-detection.policy", - "virtualhosts.virtualhost.topics.topic.slow-consumer-detection.policy"); - } - } - - public String[] getElementsProcessed() - { - return new String[]{"name"}; - } - - public String getPolicyName() - { - return getStringValue("name"); - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - if (getPolicyName() == null) - { - throw new ConfigurationException("No Slow consumer policy defined."); - } - } - - @Override - public String formatToString() - { - return "Policy:"+getPolicyName(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java deleted file mode 100644 index cb3bb5a77f..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/SlowConsumerDetectionQueueConfiguration.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class SlowConsumerDetectionQueueConfiguration extends ConfigurationPlugin -{ - private SlowConsumerPolicyPlugin _policyPlugin; - - public static class SlowConsumerDetectionQueueConfigurationFactory implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - SlowConsumerDetectionQueueConfiguration slowConsumerConfig = new SlowConsumerDetectionQueueConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList( - "virtualhosts.virtualhost.queues.slow-consumer-detection", - "virtualhosts.virtualhost.queues.queue.slow-consumer-detection", - "virtualhosts.virtualhost.topics.slow-consumer-detection", - "virtualhosts.virtualhost.topics.topic.slow-consumer-detection"); - } - } - - public String[] getElementsProcessed() - { - return new String[]{"messageAge", - "depth", - "messageCount"}; - } - - public long getMessageAge() - { - return getLongValue("messageAge"); - } - - public long getDepth() - { - return getLongValue("depth"); - } - - public long getMessageCount() - { - return getLongValue("messageCount"); - } - - public SlowConsumerPolicyPlugin getPolicy() - { - return _policyPlugin; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - PluginManager pluginManager; - try - { - pluginManager = ApplicationRegistry.getInstance().getPluginManager(); - } - catch (IllegalStateException ise) - { - // We see this happen during shutdown due to asynchronous reconfig performed IO threads - // running at the same time as the shutdown handler. - _policyPlugin = null; - return; - } - - if (!containsPositiveLong("messageAge") && - !containsPositiveLong("depth") && - !containsPositiveLong("messageCount")) - { - throw new ConfigurationException("At least one configuration property" + - "('messageAge','depth' or 'messageCount') must be specified."); - } - - SlowConsumerDetectionPolicyConfiguration policyConfig = getConfiguration(SlowConsumerDetectionPolicyConfiguration.class.getName()); - Map<String, SlowConsumerPolicyPluginFactory> factories = pluginManager.getSlowConsumerPlugins(); - - if (policyConfig == null) - { - throw new ConfigurationException("No Slow Consumer Policy specified. Known Policies:" + factories.keySet()); - } - - if (_logger.isDebugEnabled()) - { - Iterator<?> keys = policyConfig.getConfig().getKeys(); - - while (keys.hasNext()) - { - String key = (String) keys.next(); - - _logger.debug("Policy Keys:" + key); - } - - } - - SlowConsumerPolicyPluginFactory<SlowConsumerPolicyPlugin> pluginFactory = factories.get(policyConfig.getPolicyName().toLowerCase()); - - if (pluginFactory == null) - { - throw new ConfigurationException("Unknown Slow Consumer Policy specified:" + policyConfig.getPolicyName() + " Known Policies:" + factories.keySet()); - } - - _policyPlugin = pluginFactory.newInstance(policyConfig); - - // Debug the creation of this Config - _logger.debug(this); - } - - public String formatToString() - { - StringBuilder sb = new StringBuilder(); - if (getMessageAge() > 0) - { - sb.append("Age:").append(getMessageAge()).append(":"); - } - if (getDepth() > 0) - { - sb.append("Depth:").append(getDepth()).append(":"); - } - if (getMessageCount() > 0) - { - sb.append("Count:").append(getMessageCount()).append(":"); - } - - sb.append("Policy[").append(getPolicy()).append("]"); - return sb.toString(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java new file mode 100644 index 0000000000..9b06a2b499 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/AuthenticationProviderRecoverer.java @@ -0,0 +1,55 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; + +public class AuthenticationProviderRecoverer implements ConfiguredObjectRecoverer<AuthenticationProvider> +{ + private final AuthenticationProviderFactory _authenticationProviderFactory; + + public AuthenticationProviderRecoverer(AuthenticationProviderFactory authenticationProviderFactory) + { + _authenticationProviderFactory = authenticationProviderFactory; + } + + @Override + public AuthenticationProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create( + configurationEntry.getId(), + broker, + attributes, null); + + return authenticationProvider; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java new file mode 100644 index 0000000000..4bfa0ca7a3 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java @@ -0,0 +1,139 @@ +package org.apache.qpid.server.configuration.startup; + +import java.util.Collection; +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; +import org.apache.qpid.server.model.adapter.BrokerAdapter; +import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> +{ + private final StatisticsGatherer _statisticsGatherer; + private final VirtualHostRegistry _virtualHostRegistry; + private final LogRecorder _logRecorder; + private final RootMessageLogger _rootMessageLogger; + private final AuthenticationProviderFactory _authenticationProviderFactory; + private final PortFactory _portFactory; + private final TaskExecutor _taskExecutor; + + public BrokerRecoverer(AuthenticationProviderFactory authenticationProviderFactory, PortFactory portFactory, + StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, + RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor) + { + _portFactory = portFactory; + _authenticationProviderFactory = authenticationProviderFactory; + _statisticsGatherer = statisticsGatherer; + _virtualHostRegistry = virtualHostRegistry; + _logRecorder = logRecorder; + _rootMessageLogger = rootMessageLogger; + _taskExecutor = taskExecutor; + } + + @Override + public Broker create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) + { + StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore()); + BrokerAdapter broker = new BrokerAdapter(entry.getId(), entry.getAttributes(), _statisticsGatherer, _virtualHostRegistry, + _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor); + broker.addChangeListener(storeChangeListener); + Map<String, Collection<ConfigurationEntry>> childEntries = entry.getChildren(); + for (String type : childEntries.keySet()) + { + ConfiguredObjectRecoverer<?> recoverer = recovererProvider.getRecoverer(type); + if (recoverer == null) + { + throw new IllegalConfigurationException("Cannot recover entry for the type '" + type + "' from broker"); + } + Collection<ConfigurationEntry> entries = childEntries.get(type); + for (ConfigurationEntry childEntry : entries) + { + ConfiguredObject object = recoverer.create(recovererProvider, childEntry, broker); + if (object == null) + { + throw new IllegalConfigurationException("Cannot create configured object for the entry " + childEntry); + } + broker.recoverChild(object); + object.addChangeListener(storeChangeListener); + } + } + wireUpConfiguredObjects(broker, entry.getAttributes()); + + return broker; + } + + private void wireUpConfiguredObjects(BrokerAdapter broker, Map<String, Object> brokerAttributes) + { + AuthenticationProvider defaultAuthenticationProvider = null; + Collection<AuthenticationProvider> authenticationProviders = broker.getAuthenticationProviders(); + int numberOfAuthenticationProviders = authenticationProviders.size(); + if (numberOfAuthenticationProviders == 0) + { + throw new IllegalConfigurationException("No authentication provider was configured"); + } + else if (numberOfAuthenticationProviders == 1) + { + defaultAuthenticationProvider = authenticationProviders.iterator().next(); + } + else + { + String name = (String) brokerAttributes.get(Broker.DEFAULT_AUTHENTICATION_PROVIDER); + if (name == null) + { + throw new IllegalConfigurationException("Multiple authentication providers defined, but no default was configured."); + } + + defaultAuthenticationProvider = getAuthenticationProviderByName(broker, name); + } + broker.setDefaultAuthenticationProvider(defaultAuthenticationProvider); + + GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(broker.getGroupProviders()); + for (AuthenticationProvider authenticationProvider : authenticationProviders) + { + authenticationProvider.setGroupAccessor(groupPrincipalAccessor); + } + + Collection<Port> ports = broker.getPorts(); + for (Port port : ports) + { + String authenticationProviderName = (String) port.getAttribute(Port.AUTHENTICATION_MANAGER); + AuthenticationProvider provider = null; + if (authenticationProviderName != null) + { + provider = getAuthenticationProviderByName(broker, authenticationProviderName); + } + else + { + provider = defaultAuthenticationProvider; + } + port.setAuthenticationProvider(provider); + } + } + + private AuthenticationProvider getAuthenticationProviderByName(BrokerAdapter broker, String authenticationProviderName) + { + AuthenticationProvider provider = broker.getAuthenticationProviderByName(authenticationProviderName); + if (provider == null) + { + throw new IllegalConfigurationException("Cannot find the authentication provider with name: " + + authenticationProviderName); + } + return provider; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java new file mode 100644 index 0000000000..15cb229d8a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java @@ -0,0 +1,112 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory; +import org.apache.qpid.server.model.adapter.PortFactory; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.plugin.GroupManagerFactory; +import org.apache.qpid.server.plugin.PluginFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + +public class DefaultRecovererProvider implements RecovererProvider +{ + + private final StatisticsGatherer _brokerStatisticsGatherer; + private final VirtualHostRegistry _virtualHostRegistry; + private final LogRecorder _logRecorder; + private final RootMessageLogger _rootMessageLogger; + private final AuthenticationProviderFactory _authenticationProviderFactory; + private final PortFactory _portFactory; + private final QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader; + private final QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader; + private final TaskExecutor _taskExecutor; + + public DefaultRecovererProvider(StatisticsGatherer brokerStatisticsGatherer, VirtualHostRegistry virtualHostRegistry, + LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor) + { + _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>()); + _portFactory = new PortFactory(); + _brokerStatisticsGatherer = brokerStatisticsGatherer; + _virtualHostRegistry = virtualHostRegistry; + _logRecorder = logRecorder; + _rootMessageLogger = rootMessageLogger; + _groupManagerServiceLoader = new QpidServiceLoader<GroupManagerFactory>(); + _pluginFactoryServiceLoader = new QpidServiceLoader<PluginFactory>(); + _taskExecutor = taskExecutor; + } + + @Override + public ConfiguredObjectRecoverer<?> getRecoverer(String type) + { + if (Broker.class.getSimpleName().equals(type)) + { + return new BrokerRecoverer(_authenticationProviderFactory, _portFactory, _brokerStatisticsGatherer, _virtualHostRegistry, + _logRecorder, _rootMessageLogger, _taskExecutor); + } + else if(VirtualHost.class.getSimpleName().equals(type)) + { + return new VirtualHostRecoverer(_brokerStatisticsGatherer); + } + else if(AuthenticationProvider.class.getSimpleName().equals(type)) + { + return new AuthenticationProviderRecoverer(_authenticationProviderFactory); + } + else if(Port.class.getSimpleName().equals(type)) + { + return new PortRecoverer(_portFactory); + } + else if(GroupProvider.class.getSimpleName().equals(type)) + { + return new GroupProviderRecoverer(_groupManagerServiceLoader); + } + else if(KeyStore.class.getSimpleName().equals(type)) + { + return new KeyStoreRecoverer(); + } + else if(TrustStore.class.getSimpleName().equals(type)) + { + return new TrustStoreRecoverer(); + } + else if(Plugin.class.getSimpleName().equals(type)) + { + return new PluginRecoverer(_pluginFactoryServiceLoader); + } + + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java new file mode 100644 index 0000000000..275a0c736c --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/GroupProviderRecoverer.java @@ -0,0 +1,74 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import java.util.Map; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.adapter.GroupProviderAdapter; +import org.apache.qpid.server.plugin.GroupManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.group.GroupManager; + +public class GroupProviderRecoverer implements ConfiguredObjectRecoverer<GroupProvider> +{ + private QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader; + + public GroupProviderRecoverer(QpidServiceLoader<GroupManagerFactory> groupManagerServiceLoader) + { + super(); + _groupManagerServiceLoader = groupManagerServiceLoader; + } + + @Override + public GroupProvider create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + GroupManager groupManager = createGroupManager(attributes); + if (groupManager == null) + { + throw new IllegalConfigurationException("Cannot create GroupManager from attributes : " + attributes); + } + GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(configurationEntry.getId(), groupManager, broker); + return groupProviderAdapter; + } + + private GroupManager createGroupManager(Map<String, Object> attributes) + { + for(GroupManagerFactory factory : _groupManagerServiceLoader.instancesOf(GroupManagerFactory.class)) + { + GroupManager groupManager = factory.createInstance(attributes); + if (groupManager != null) + { + return groupManager; + } + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java index 833ccfbca4..8efedd37b5 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/KeyStoreRecoverer.java @@ -18,30 +18,23 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.configuration.startup; -import org.apache.qpid.transport.codec.BBEncoder; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.adapter.KeyStoreAdapter; -public abstract class QMFEventCommand<T extends QMFEventClass> extends QMFCommand +public class KeyStoreRecoverer implements ConfiguredObjectRecoverer<KeyStore> { - private final long _timestamp; - - protected QMFEventCommand() - { - super(new QMFCommandHeader((byte)'2',0, QMFOperation.EVENT)); - _timestamp = System.currentTimeMillis(); - } - - abstract public T getEventClass(); - @Override - public void encode(final BBEncoder encoder) + public KeyStore create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) { - super.encode(encoder); - encoder.writeStr8(getEventClass().getPackage().getName()); - encoder.writeStr8(getEventClass().getName()); - encoder.writeBin128(new byte[16]); - encoder.writeUint64(_timestamp * 1000000L); - encoder.writeUint8((short) getEventClass().getSeverity().ordinal()); + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + return new KeyStoreAdapter(entry.getId(), broker, entry.getAttributes()); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java new file mode 100644 index 0000000000..ddc4482953 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PluginRecoverer.java @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.plugin.PluginFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +public class PluginRecoverer implements ConfiguredObjectRecoverer<ConfiguredObject> +{ + private QpidServiceLoader<PluginFactory> _serviceLoader; + + public PluginRecoverer(QpidServiceLoader<PluginFactory> serviceLoader) + { + _serviceLoader = serviceLoader; + } + + @Override + public ConfiguredObject create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + Map<String, Object> attributes = configurationEntry.getAttributes(); + Iterable<PluginFactory> factories = _serviceLoader.instancesOf(PluginFactory.class); + for (PluginFactory pluginFactory : factories) + { + UUID configurationId = configurationEntry.getId(); + ConfiguredObject pluginObject = pluginFactory.createInstance(configurationId, attributes, broker); + if (pluginObject != null) + { + UUID pluginId = pluginObject.getId(); + if (!configurationId.equals(pluginId)) + { + throw new IllegalStateException("Plugin object id '" + pluginId + "' does not equal expected id " + configurationId); + } + return pluginObject; + } + } + throw new IllegalConfigurationException("Cannot create a plugin object for " + attributes + " with factories " + factories); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java new file mode 100644 index 0000000000..147e835a8d --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/PortRecoverer.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.adapter.BrokerAdapter; +import org.apache.qpid.server.model.adapter.PortFactory; + +public class PortRecoverer implements ConfiguredObjectRecoverer<Port> +{ + /** + * delegates to a {@link PortFactory} so that the logic can be shared by + * {@link BrokerAdapter} + */ + private final PortFactory _portFactory; + + public PortRecoverer(PortFactory portFactory) + { + _portFactory = portFactory; + } + + @Override + public Port create(RecovererProvider recovererProvider, ConfigurationEntry configurationEntry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + return _portFactory.createPort(configurationEntry.getId(), broker, configurationEntry.getAttributes()); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java index 9c8fa1e2c6..b60c9c289f 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFPackageIndicationCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/RecovererHelper.java @@ -18,27 +18,27 @@ * under the License. * */ +package org.apache.qpid.server.configuration.startup; -package org.apache.qpid.qmf; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFPackageIndicationCommand extends QMFCommand +public class RecovererHelper { - private String _supportedSchema; - - public QMFPackageIndicationCommand(QMFPackageQueryCommand qmfPackageQueryCommand, String supportedSchema) - { - super( new QMFCommandHeader(qmfPackageQueryCommand.getHeader().getVersion(), - qmfPackageQueryCommand.getHeader().getSeq(), - QMFOperation.PACKAGE_INDICATION)); - _supportedSchema = supportedSchema; - - } - - public void encode(BBEncoder encoder) + public static Broker verifyOnlyBrokerIsParent(ConfiguredObject... parents) { - super.encode(encoder); - encoder.writeStr8(_supportedSchema); + if (parents == null || parents.length == 0) + { + throw new IllegalArgumentException("Broker parent is not passed!"); + } + if (parents.length != 1) + { + throw new IllegalArgumentException("Only one parent is expected!"); + } + if (!(parents[0] instanceof Broker)) + { + throw new IllegalArgumentException("Parent is not a broker"); + } + return (Broker)parents[0]; } } diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java index 613e1e5978..7e9428a4d6 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFClassIndicationCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/TrustStoreRecoverer.java @@ -18,31 +18,23 @@ * under the License. * */ +package org.apache.qpid.server.configuration.startup; -package org.apache.qpid.qmf; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.model.adapter.TrustStoreAdapter; -import org.apache.qpid.transport.codec.BBEncoder; - -public class QMFClassIndicationCommand extends QMFCommand +public class TrustStoreRecoverer implements ConfiguredObjectRecoverer<TrustStore> { - private QMFClass _qmfClass; - - public QMFClassIndicationCommand(QMFClassQueryCommand qmfClassQueryCommand, QMFClass qmfClass) - { - super(new QMFCommandHeader(qmfClassQueryCommand.getHeader().getVersion(), - qmfClassQueryCommand.getHeader().getSeq(), - QMFOperation.CLASS_INDICATION)); - _qmfClass = qmfClass; - } - - @Override - public void encode(BBEncoder encoder) + public TrustStore create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) { - super.encode(encoder); - encoder.writeUint8(_qmfClass.getType().getValue()); - encoder.writeStr8(_qmfClass.getPackage().getName()); - encoder.writeStr8(_qmfClass.getName()); - encoder.writeBin128(_qmfClass.getSchemaHash()); + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + return new TrustStoreAdapter(entry.getId(), broker, entry.getAttributes()); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java new file mode 100644 index 0000000000..4f863adfb5 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/VirtualHostRecoverer.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.adapter.VirtualHostAdapter; +import org.apache.qpid.server.stats.StatisticsGatherer; + +public class VirtualHostRecoverer implements ConfiguredObjectRecoverer<VirtualHost> +{ + private StatisticsGatherer _brokerStatisticsGatherer; + + public VirtualHostRecoverer(StatisticsGatherer brokerStatisticsGatherer) + { + super(); + _brokerStatisticsGatherer = brokerStatisticsGatherer; + } + + @Override + public VirtualHost create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents) + { + Broker broker = RecovererHelper.verifyOnlyBrokerIsParent(parents); + + return new VirtualHostAdapter(entry.getId(), entry.getAttributes(), broker, _brokerStatisticsGatherer, broker.getTaskExecutor()); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java new file mode 100644 index 0000000000..e11b63001a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/JsonConfigurationEntryStore.java @@ -0,0 +1,711 @@ +package org.apache.qpid.server.configuration.store; + +import static org.apache.qpid.server.configuration.ConfigurationEntry.ATTRIBUTE_NAME; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.util.FileUtils; +import org.apache.qpid.util.Strings; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig; +import org.codehaus.jackson.node.ArrayNode; + +public class JsonConfigurationEntryStore implements ConfigurationEntryStore +{ + public static final String STORE_TYPE = "json"; + public static final String IN_MEMORY = ":memory:"; + + private static final String DEFAULT_BROKER_NAME = "Broker"; + private static final String ID = "id"; + private static final String TYPE = "@type"; + + private ObjectMapper _objectMapper; + private Map<UUID, ConfigurationEntry> _entries; + private File _storeFile; + private UUID _rootId; + private Map<String, Class<? extends ConfiguredObject>> _relationshipClasses; + + public JsonConfigurationEntryStore() + { + _objectMapper = new ObjectMapper(); + _objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); + _objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + _entries = new HashMap<UUID, ConfigurationEntry>(); + _relationshipClasses = buildRelationshipClassMap(); + } + + @Override + public void open(String storeLocation) + { + if (_rootId != null) + { + throw new IllegalConfigurationException("The store has been opened alread"); + } + if (!IN_MEMORY.equals(storeLocation)) + { + _storeFile = new File(storeLocation); + } + createOrLoadStore(); + } + + @Override + public void open(String storeLocation, String initialStoreLocation) + { + if (_rootId != null) + { + throw new IllegalConfigurationException("The store has been opened already"); + } + if (!IN_MEMORY.equals(storeLocation)) + { + _storeFile = new File(storeLocation); + if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStoreLocation != null) + { + copyInitialStoreFile(initialStoreLocation); + } + createOrLoadStore(); + } + else + { + if (initialStoreLocation == null) + { + createRootEntryIfNotExists(); + } + else + { + load(toURL(initialStoreLocation)); + } + } + } + + @Override + public void open(String storeLocation, ConfigurationEntryStore initialStore) + { + if (_rootId != null) + { + throw new IllegalConfigurationException("The store has been opened already"); + } + boolean copyStore = false; + if (IN_MEMORY.equals(storeLocation)) + { + copyStore = initialStore != null; + } + else + { + _storeFile = new File(storeLocation); + if ((!_storeFile.exists() || _storeFile.length() == 0) && initialStore != null) + { + createStoreFileIfNotExist(_storeFile); + copyStore = true; + } + } + if (copyStore) + { + ConfigurationEntry rootEntry = initialStore.getRootEntry(); + _rootId = rootEntry.getId(); + copyEntry(rootEntry.getId(), initialStore); + saveAsTree(); + } + else + { + createOrLoadStore(); + } + } + + @Override + public synchronized UUID[] remove(UUID... entryIds) + { + List<UUID> removedIds = new ArrayList<UUID>(); + boolean anyRemoved = false; + for (UUID uuid : entryIds) + { + if (_rootId.equals(uuid)) + { + throw new IllegalConfigurationException("Cannot remove root entry"); + } + } + for (UUID uuid : entryIds) + { + if (removeInternal(uuid)) + { + anyRemoved = true; + + // remove references to the entry from parent entries + for (ConfigurationEntry entry : _entries.values()) + { + if (entry.hasChild(uuid)) + { + Set<UUID> children = new HashSet<UUID>(entry.getChildrenIds()); + children.remove(uuid); + ConfigurationEntry referal = new ConfigurationEntry(entry.getId(), entry.getType(), + entry.getAttributes(), children, this); + _entries.put(entry.getId(), referal); + } + } + removedIds.add(uuid); + } + } + if (anyRemoved) + { + saveAsTree(); + } + return removedIds.toArray(new UUID[removedIds.size()]); + } + + @Override + public synchronized void save(ConfigurationEntry... entries) + { + boolean anySaved = false; + for (ConfigurationEntry entry : entries) + { + ConfigurationEntry oldEntry = _entries.put(entry.getId(), entry); + if (!entry.equals(oldEntry)) + { + anySaved = true; + } + } + if (anySaved) + { + saveAsTree(); + } + } + + @Override + public ConfigurationEntry getRootEntry() + { + return getEntry(_rootId); + } + + @Override + public synchronized ConfigurationEntry getEntry(UUID id) + { + return _entries.get(id); + } + + @Override + public void copyTo(String copyLocation) + { + if (_rootId == null) + { + throw new IllegalConfigurationException("The store has not been opened"); + } + File file = new File(copyLocation); + if (!file.exists()) + { + createStoreFileIfNotExist(file); + } + saveAsTree(_rootId, _entries, _objectMapper, file); + } + + @Override + public String toString() + { + return "JsonConfigurationEntryStore [_storeFile=" + _storeFile + ", _rootId=" + _rootId + "]"; + } + + private Map<String, Class<? extends ConfiguredObject>> buildRelationshipClassMap() + { + Map<String, Class<? extends ConfiguredObject>> relationships = new HashMap<String, Class<? extends ConfiguredObject>>(); + + Collection<Class<? extends ConfiguredObject>> children = Model.getInstance().getChildTypes(Broker.class); + for (Class<? extends ConfiguredObject> childClass : children) + { + String name = childClass.getSimpleName().toLowerCase(); + String relationshipName = name + (name.endsWith("s") ? "es" : "s"); + relationships.put(relationshipName, childClass); + } + return relationships; + } + + private void createOrLoadStore() + { + if (_storeFile != null) + { + if (!_storeFile.exists() || _storeFile.length() == 0) + { + createStoreFileIfNotExist(_storeFile); + } + else + { + load(fileToURL(_storeFile)); + } + } + + createRootEntryIfNotExists(); + } + + private void createRootEntryIfNotExists() + { + if (_rootId == null) + { + // create a root entry for an empty store + ConfigurationEntry brokerEntry = new ConfigurationEntry(UUIDGenerator.generateRandomUUID(), + Broker.class.getSimpleName(), Collections.<String, Object> emptyMap(), Collections.<UUID> emptySet(), this); + _rootId = brokerEntry.getId(); + _entries.put(_rootId, brokerEntry); + } + } + + private void load(URL url) + { + InputStream is = null; + try + { + is = url.openStream(); + JsonNode node = loadJsonNodes(is, _objectMapper); + ConfigurationEntry brokerEntry = toEntry(node, Broker.class, _entries); + _rootId = brokerEntry.getId(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot load store from: " + url, e); + } + finally + { + if (is != null) + { + if (is != null) + { + try + { + is.close(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot close input stream for: " + url, e); + } + } + } + } + } + + private void copyInitialStoreFile(String initialStoreLocation) + { + createStoreFileIfNotExist(_storeFile); + URL initialStoreURL = toURL(initialStoreLocation); + InputStream in = null; + try + { + in = initialStoreURL.openStream(); + FileUtils.copy(in, _storeFile); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot create store file " + _storeFile + " by copying initial store from " + initialStoreLocation , e); + } + finally + { + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot close initial store input stream: " + initialStoreLocation , e); + } + } + } + } + + private URL fileToURL(File storeFile) + { + URL storeURL = null; + try + { + storeURL = storeFile.toURI().toURL(); + } + catch (MalformedURLException e) + { + throw new IllegalConfigurationException("Cannot create URL for file " + storeFile, e); + } + return storeURL; + } + + private boolean removeInternal(UUID entryId) + { + ConfigurationEntry oldEntry = _entries.remove(entryId); + if (oldEntry != null) + { + Set<UUID> children = oldEntry.getChildrenIds(); + if (children != null && !children.isEmpty()) + { + for (UUID childId : children) + { + removeInternal(childId); + } + } + return true; + } + return false; + } + + private void saveAsTree() + { + if (_storeFile != null) + { + saveAsTree(_rootId, _entries, _objectMapper, _storeFile); + } + } + + private void saveAsTree(UUID rootId, Map<UUID, ConfigurationEntry> entries, ObjectMapper mapper, File file) + { + Map<String, Object> tree = toTree(rootId, entries); + try + { + mapper.writeValue(file, tree); + } + catch (JsonGenerationException e) + { + throw new IllegalConfigurationException("Cannot generate json!", e); + } + catch (JsonMappingException e) + { + throw new IllegalConfigurationException("Cannot map objects for json serialization!", e); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot save configuration into " + file + "!", e); + } + } + + private Map<String, Object> toTree(UUID rootId, Map<UUID, ConfigurationEntry> entries) + { + ConfigurationEntry entry = entries.get(rootId); + if (entry == null || !entry.getId().equals(rootId)) + { + throw new IllegalConfigurationException("Cannot find entry with id " + rootId + "!"); + } + Map<String, Object> tree = new TreeMap<String, Object>(); + Map<String, Object> attributes = entry.getAttributes(); + if (attributes != null) + { + tree.putAll(attributes); + } + tree.put(ID, entry.getId()); + tree.put(TYPE, entry.getType()); + Set<UUID> childrenIds = entry.getChildrenIds(); + if (childrenIds != null && !childrenIds.isEmpty()) + { + for (UUID relationship : childrenIds) + { + ConfigurationEntry child = entries.get(relationship); + if (child != null) + { + String relationshipName = child.getType().toLowerCase() + "s"; + + @SuppressWarnings("unchecked") + Collection<Map<String, Object>> children = (Collection<Map<String, Object>>) tree.get(relationshipName); + if (children == null) + { + children = new ArrayList<Map<String, Object>>(); + tree.put(relationshipName, children); + } + Map<String, Object> childAsMap = toTree(relationship, entries); + children.add(childAsMap); + } + } + } + return tree; + } + + private JsonNode loadJsonNodes(InputStream is, ObjectMapper mapper) + { + JsonNode root = null; + try + { + root = mapper.readTree(is); + } + catch (JsonProcessingException e) + { + throw new IllegalConfigurationException("Cannot parse json", e); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot read json", e); + } + return root; + } + + private ConfigurationEntry toEntry(JsonNode parent, Class<? extends ConfiguredObject> expectedConfiguredObjectClass, Map<UUID, ConfigurationEntry> entries) + { + Map<String, Object> attributes = null; + Set<UUID> childrenIds = new TreeSet<UUID>(); + Iterator<String> fieldNames = parent.getFieldNames(); + String type = null; + String idAsString = null; + while (fieldNames.hasNext()) + { + String fieldName = fieldNames.next(); + JsonNode fieldNode = parent.get(fieldName); + if (fieldName.equals(ID)) + { + idAsString = fieldNode.asText(); + } + else if (fieldName.equals(TYPE)) + { + type = fieldNode.asText(); + } + else if (fieldNode.isArray()) + { + // array containing either broker children or attribute values + Iterator<JsonNode> elements = fieldNode.getElements(); + List<Object> fieldValues = null; + while (elements.hasNext()) + { + JsonNode element = elements.next(); + if (element.isObject()) + { + Class<? extends ConfiguredObject> expectedChildConfiguredObjectClass = _relationshipClasses.get(fieldName); + // assuming it is a child node + ConfigurationEntry entry = toEntry(element, expectedChildConfiguredObjectClass, entries); + childrenIds.add(entry.getId()); + } + else + { + if (fieldValues == null) + { + fieldValues = new ArrayList<Object>(); + } + fieldValues.add(toObject(element)); + } + } + if (fieldValues != null) + { + Object[] array = fieldValues.toArray(new Object[fieldValues.size()]); + attributes.put(fieldName, array); + } + } + else if (fieldNode.isObject()) + { + // ignore, in-line objects are not supported yet + } + else + { + // primitive attribute + Object value = toObject(fieldNode); + if (attributes == null) + { + attributes = new HashMap<String, Object>(); + } + attributes.put(fieldName, value); + } + } + + if (type == null) + { + if (expectedConfiguredObjectClass == null) + { + throw new IllegalConfigurationException("Type attribute is not provided for configuration entry " + parent); + } + else + { + type = expectedConfiguredObjectClass.getSimpleName(); + } + } + String name = null; + if (attributes != null) + { + name = (String) attributes.get(ATTRIBUTE_NAME); + } + if ((name == null || "".equals(name))) + { + if (expectedConfiguredObjectClass == Broker.class) + { + name = DEFAULT_BROKER_NAME; + } + else + { + throw new IllegalConfigurationException("Name attribute is not provided for configuration entry " + parent); + } + } + UUID id = null; + if (idAsString == null) + { + if (expectedConfiguredObjectClass == Broker.class) + { + id = UUIDGenerator.generateRandomUUID(); + } + else + { + id = UUIDGenerator.generateBrokerChildUUID(type, name); + } + } + else + { + try + { + id = UUID.fromString(idAsString); + } + catch (Exception e) + { + throw new IllegalConfigurationException( + "ID attribute value does not conform to UUID format for configuration entry " + parent); + } + } + ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, childrenIds, this); + if (entries.containsKey(id)) + { + throw new IllegalConfigurationException("Duplicate id is found: " + id + + "! The following configuration entries have the same id: " + entries.get(id) + ", " + entry); + } + entries.put(id, entry); + return entry; + } + + private Object toObject(JsonNode node) + { + if (node.isValueNode()) + { + if (node.isBoolean()) + { + return node.asBoolean(); + } + else if (node.isDouble()) + { + return node.asDouble(); + } + else if (node.isInt()) + { + return node.asInt(); + } + else if (node.isLong()) + { + return node.asLong(); + } + else if (node.isNull()) + { + return null; + } + else + { + return Strings.expand(node.asText()); + } + } + else if (node.isArray()) + { + return toArray(node); + } + else if (node.isObject()) + { + return toMap(node); + } + else + { + throw new IllegalConfigurationException("Unexpected node: " + node); + } + } + + private Map<String, Object> toMap(JsonNode node) + { + Map<String, Object> object = new TreeMap<String, Object>(); + Iterator<String> fieldNames = node.getFieldNames(); + while (fieldNames.hasNext()) + { + String name = fieldNames.next(); + Object value = toObject(node.get(name)); + object.put(name, value); + } + return object; + } + + private Object toArray(JsonNode node) + { + ArrayNode arrayNode = (ArrayNode) node; + Object[] array = new Object[arrayNode.size()]; + Iterator<JsonNode> elements = arrayNode.getElements(); + for (int i = 0; i < array.length; i++) + { + array[i] = toObject(elements.next()); + } + return array; + } + + /* + * Initial store location can be URL or absolute path + */ + private URL toURL(String location) + { + URL url = null; + try + { + url = new URL(location); + } + catch (MalformedURLException e) + { + File locationFile = new File(location); + url = fileToURL(locationFile); + } + return url; + } + + private void createStoreFileIfNotExist(File file) + { + File parent = file.getParentFile(); + if (!parent.exists()) + { + if (!parent.mkdirs()) + { + throw new IllegalConfigurationException("Cannot create folders " + parent); + } + } + try + { + file.createNewFile(); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot create file " + file, e); + } + } + + private void copyEntry(UUID entryId, ConfigurationEntryStore initialStore) + { + ConfigurationEntry entry = initialStore.getEntry(entryId); + if (entry != null) + { + if (_entries.containsKey(entryId)) + { + throw new IllegalConfigurationException("Duplicate id is found: " + entryId + + "! The following configuration entries have the same id: " + _entries.get(entryId) + ", " + entry); + } + _entries.put(entryId, entry); + Set<UUID> children = entry.getChildrenIds(); + if (children != null) + { + for (UUID uuid : children) + { + copyEntry(uuid, initialStore); + } + } + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java new file mode 100644 index 0000000000..e7c474bf55 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java @@ -0,0 +1,327 @@ +package org.apache.qpid.server.configuration.store; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.BrokerOptions; +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.util.MapValueConverter; + +public class ManagementModeStoreHandler implements ConfigurationEntryStore +{ + private static final Logger LOGGER = Logger.getLogger(ManagementModeStoreHandler.class); + + private static final String MANAGEMENT_MODE_PORT_PREFIX = "MANAGEMENT-MODE-PORT-"; + private static final String PORT_TYPE = Port.class.getSimpleName(); + private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName(); + private static final String ATTRIBUTE_STATE = VirtualHost.STATE; + + private final ConfigurationEntryStore _store; + private final Map<UUID, ConfigurationEntry> _cliEntries; + private final Map<UUID, Object> _quiescedEntries; + private final UUID _rootId; + + public ManagementModeStoreHandler(ConfigurationEntryStore store, BrokerOptions options) + { + ConfigurationEntry storeRoot = store.getRootEntry(); + _store = store; + _rootId = storeRoot.getId(); + _cliEntries = createPortsFromCommadLineOptions(options); + _quiescedEntries = quiesceEntries(storeRoot, options); + } + + @Override + public void open(String storeLocation) + { + throw new IllegalStateException("The store should be already opened"); + } + + @Override + public void open(String storeLocation, String initialStoreLocation) + { + throw new IllegalStateException("The store should be already opened"); + } + + @Override + public void open(String storeLocation, ConfigurationEntryStore initialStore) + { + throw new IllegalStateException("The store should be already opened"); + } + + @Override + public ConfigurationEntry getRootEntry() + { + return getEntry(_rootId); + } + + @Override + public ConfigurationEntry getEntry(UUID id) + { + synchronized (_store) + { + if (_cliEntries.containsKey(id)) + { + return _cliEntries.get(id); + } + + ConfigurationEntry entry = _store.getEntry(id); + if (_quiescedEntries.containsKey(id)) + { + entry = createEntryWithState(entry, State.QUIESCED); + } + else if (id == _rootId) + { + entry = createRootWithCLIEntries(entry); + } + return entry; + } + } + + @Override + public void save(ConfigurationEntry... entries) + { + synchronized (_store) + { + ConfigurationEntry[] entriesToSave = new ConfigurationEntry[entries.length]; + + for (int i = 0; i < entries.length; i++) + { + ConfigurationEntry entry = entries[i]; + UUID id = entry.getId(); + if (_cliEntries.containsKey(id)) + { + throw new IllegalConfigurationException("Cannot save configuration provided as command line argument:" + + entry); + } + else if (_quiescedEntries.containsKey(id)) + { + // save entry with the original state + entry = createEntryWithState(entry, _quiescedEntries.get(ATTRIBUTE_STATE)); + } + else if (_rootId.equals(id)) + { + // save root without command line entries + Set<UUID> childrenIds = new HashSet<UUID>(entry.getChildrenIds()); + if (!_cliEntries.isEmpty()) + { + childrenIds.removeAll(_cliEntries.entrySet()); + } + HashMap<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes()); + entry = new ConfigurationEntry(entry.getId(), entry.getType(), attributes, childrenIds, this); + } + entriesToSave[i] = entry; + } + + _store.save(entriesToSave); + } + } + + @Override + public UUID[] remove(UUID... entryIds) + { + synchronized (_store) + { + for (UUID id : entryIds) + { + if (_cliEntries.containsKey(id)) + { + throw new IllegalConfigurationException("Cannot change configuration for command line entry:" + + _cliEntries.get(id)); + } + } + UUID[] result = _store.remove(entryIds); + for (UUID id : entryIds) + { + if (_quiescedEntries.containsKey(id)) + { + _quiescedEntries.remove(id); + } + } + return result; + } + } + + @Override + public void copyTo(String copyLocation) + { + synchronized (_store) + { + _store.copyTo(copyLocation); + } + } + + private Map<UUID, ConfigurationEntry> createPortsFromCommadLineOptions(BrokerOptions options) + { + int managementModeRmiPort = options.getManagementModeRmiPort(); + if (managementModeRmiPort < 0) + { + throw new IllegalConfigurationException("Invalid rmi port is specified: " + managementModeRmiPort); + } + int managementModeConnectorPort = options.getManagementModeConnectorPort(); + if (managementModeConnectorPort < 0) + { + throw new IllegalConfigurationException("Invalid connector port is specified: " + managementModeConnectorPort); + } + int managementModeHttpPort = options.getManagementModeHttpPort(); + if (managementModeHttpPort < 0) + { + throw new IllegalConfigurationException("Invalid http port is specified: " + managementModeHttpPort); + } + Map<UUID, ConfigurationEntry> cliEntries = new HashMap<UUID, ConfigurationEntry>(); + if (managementModeRmiPort != 0) + { + ConfigurationEntry entry = createCLIPortEntry(managementModeRmiPort, Protocol.RMI); + cliEntries.put(entry.getId(), entry); + if (managementModeConnectorPort == 0) + { + ConfigurationEntry connectorEntry = createCLIPortEntry(managementModeRmiPort + 100, Protocol.JMX_RMI); + cliEntries.put(connectorEntry.getId(), connectorEntry); + } + } + if (managementModeConnectorPort != 0) + { + ConfigurationEntry entry = createCLIPortEntry(managementModeConnectorPort, Protocol.JMX_RMI); + cliEntries.put(entry.getId(), entry); + } + if (managementModeHttpPort != 0) + { + ConfigurationEntry entry = createCLIPortEntry(managementModeHttpPort, Protocol.HTTP); + cliEntries.put(entry.getId(), entry); + } + return cliEntries; + } + + private ConfigurationEntry createCLIPortEntry(int port, Protocol protocol) + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(Port.PORT, port); + attributes.put(Port.PROTOCOLS, Collections.singleton(protocol)); + attributes.put(Port.NAME, MANAGEMENT_MODE_PORT_PREFIX + protocol.name()); + ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), PORT_TYPE, attributes, + Collections.<UUID> emptySet(), this); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Add management mode port configuration " + portEntry + " for port " + port + " and protocol " + + protocol); + } + return portEntry; + } + + private ConfigurationEntry createRootWithCLIEntries(ConfigurationEntry storeRoot) + { + Set<UUID> childrenIds = new HashSet<UUID>(storeRoot.getChildrenIds()); + if (!_cliEntries.isEmpty()) + { + childrenIds.addAll(_cliEntries.keySet()); + } + ConfigurationEntry root = new ConfigurationEntry(storeRoot.getId(), storeRoot.getType(), new HashMap<String, Object>( + storeRoot.getAttributes()), childrenIds, this); + return root; + } + + private Map<UUID, Object> quiesceEntries(ConfigurationEntry storeRoot, BrokerOptions options) + { + Map<UUID, Object> quiescedEntries = new HashMap<UUID, Object>(); + Set<UUID> childrenIds; + int managementModeRmiPort = options.getManagementModeRmiPort(); + int managementModeConnectorPort = options.getManagementModeConnectorPort(); + int managementModeHttpPort = options.getManagementModeHttpPort(); + childrenIds = storeRoot.getChildrenIds(); + for (UUID id : childrenIds) + { + ConfigurationEntry entry = _store.getEntry(id); + String entryType = entry.getType(); + Map<String, Object> attributes = entry.getAttributes(); + boolean quiesce = false; + if (VIRTUAL_HOST_TYPE.equals(entryType)) + { + quiesce = true; + } + else if (PORT_TYPE.equalsIgnoreCase(entryType)) + { + if (attributes == null) + { + throw new IllegalConfigurationException("Port attributes are not set in " + entry); + } + Set<Protocol> protocols = getPortProtocolsAttribute(attributes); + if (protocols == null) + { + quiesce = true; + } + else + { + for (Protocol protocol : protocols) + { + switch (protocol) + { + case JMX_RMI: + quiesce = managementModeConnectorPort > 0 || managementModeRmiPort > 0; + break; + case RMI: + quiesce = managementModeRmiPort > 0; + break; + case HTTP: + case HTTPS: + quiesce = managementModeHttpPort > 0; + break; + default: + quiesce = true; + } + } + } + } + if (quiesce) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Management mode quiescing entry " + entry); + } + + // save original state + quiescedEntries.put(entry.getId(), attributes.get(ATTRIBUTE_STATE)); + } + } + return quiescedEntries; + } + + private Set<Protocol> getPortProtocolsAttribute(Map<String, Object> attributes) + { + Object object = attributes.get(Port.PROTOCOLS); + if (object == null) + { + return null; + } + return MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, attributes, Protocol.class); + } + + private ConfigurationEntry createEntryWithState(ConfigurationEntry entry, Object state) + { + Map<String, Object> attributes = new HashMap<String, Object>(entry.getAttributes()); + if (state == null) + { + attributes.remove(ATTRIBUTE_STATE); + } + else + { + attributes.put(ATTRIBUTE_STATE, state); + } + Set<UUID> originalChildren = entry.getChildrenIds(); + Set<UUID> children = null; + if (originalChildren != null) + { + children = new HashSet<UUID>(originalChildren); + } + return new ConfigurationEntry(entry.getId(), entry.getType(), attributes, children, entry.getStore()); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java new file mode 100644 index 0000000000..813702d0a6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java @@ -0,0 +1,205 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.store; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfigurationChangeListener; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; + +public class StoreConfigurationChangeListener implements ConfigurationChangeListener +{ + private ConfigurationEntryStore _store; + + public StoreConfigurationChangeListener(ConfigurationEntryStore store) + { + super(); + _store = store; + } + + @Override + public void stateChanged(ConfiguredObject object, State oldState, State newState) + { + if (newState == State.DELETED) + { + _store.remove(object.getId()); + object.removeChangeListener(this); + } + } + + @Override + public void childAdded(ConfiguredObject object, ConfiguredObject child) + { + // exclude VirtualHost children from storing in broker store + if (!(object instanceof VirtualHost)) + { + child.addChangeListener(this); + ConfigurationEntry parentEntry = toConfigurationEntry(object); + ConfigurationEntry childEntry = toConfigurationEntry(child); + _store.save(parentEntry, childEntry); + } + + } + + @Override + public void childRemoved(ConfiguredObject object, ConfiguredObject child) + { + _store.save(toConfigurationEntry(object)); + } + + @Override + public void attributeSet(ConfiguredObject object, String attrinuteName, Object oldAttributeValue, Object newAttributeValue) + { + _store.save(toConfigurationEntry(object)); + } + + private ConfigurationEntry toConfigurationEntry(ConfiguredObject object) + { + Class<? extends ConfiguredObject> objectType = getConfiguredObjectType(object); + Set<UUID> childrenIds = getChildernIds(object, objectType); + ConfigurationEntry entry = new ConfigurationEntry(object.getId(), objectType.getSimpleName(), + object.getActualAttributes(), childrenIds, _store); + return entry; + } + + private Set<UUID> getChildernIds(ConfiguredObject object, Class<? extends ConfiguredObject> objectType) + { + // Virtual Host children's IDs should not be stored in broker store + if (object instanceof VirtualHost) + { + return Collections.emptySet(); + } + Set<UUID> childrenIds = new TreeSet<UUID>(); + Collection<Class<? extends ConfiguredObject>> childClasses = Model.getInstance().getChildTypes(objectType); + if (childClasses != null) + { + for (Class<? extends ConfiguredObject> childClass : childClasses) + { + Collection<? extends ConfiguredObject> children = object.getChildren(childClass); + if (children != null) + { + for (ConfiguredObject childObject : children) + { + childrenIds.add(childObject.getId()); + } + } + } + } + return childrenIds; + } + + private Class<? extends ConfiguredObject> getConfiguredObjectType(ConfiguredObject object) + { + if (object instanceof Broker) + { + return Broker.class; + } + return getConfiguredObjectTypeFromImplementedInterfaces(object.getClass()); + } + + @SuppressWarnings("unchecked") + private Class<? extends ConfiguredObject> getConfiguredObjectTypeFromImplementedInterfaces(Class<?> objectClass) + { + // get all implemented interfaces extending ConfiguredObject + Set<Class<?>> interfaces = getImplementedInterfacesExtendingSuper(objectClass, ConfiguredObject.class); + + if (interfaces.size() == 0) + { + throw new RuntimeException("Can not identify the configured object type"); + } + + if (interfaces.size() == 1) + { + return (Class<? extends ConfiguredObject>)interfaces.iterator().next(); + } + + Set<Class<?>> superInterfaces = new HashSet<Class<?>>(); + + // find all super interfaces + for (Class<?> interfaceClass : interfaces) + { + for (Class<?> interfaceClass2 : interfaces) + { + if (interfaceClass != interfaceClass2) + { + if (interfaceClass.isAssignableFrom(interfaceClass2)) + { + superInterfaces.add(interfaceClass); + } + } + } + } + + // remove super interfaces + for (Class<?> superInterface : superInterfaces) + { + interfaces.remove(superInterface); + } + + if (interfaces.size() == 1) + { + return (Class<? extends ConfiguredObject>)interfaces.iterator().next(); + } + else + { + throw new RuntimeException("Can not identify the configured object type as an it implements" + + " more than one configured object interfaces: " + interfaces); + } + + } + + private Set<Class<?>> getImplementedInterfacesExtendingSuper(Class<?> classInstance, Class<?> superInterface) + { + Set<Class<?>> interfaces = new HashSet<Class<?>>(); + Class<?>[] classInterfaces = classInstance.getInterfaces(); + for (Class<?> interfaceClass : classInterfaces) + { + if (interfaceClass!= superInterface && superInterface.isAssignableFrom(interfaceClass)) + { + interfaces.add(interfaceClass); + } + } + Class<?> superClass = classInstance.getSuperclass(); + if (superClass != null) + { + Set<Class<?>> superClassInterfaces = getImplementedInterfacesExtendingSuper(superClass, superInterface); + interfaces.addAll(superClassInterfaces); + } + return interfaces; + } + + @Override + public String toString() + { + return "StoreConfigurationChangeListener [store=" + _store + "]"; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java index ec471f18e8..e37e58b840 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventClass.java +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/store/factory/JsonConfigurationStoreFactory.java @@ -18,25 +18,24 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.configuration.store.factory; -import java.util.List; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.ConfigurationStoreFactory; +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; -public abstract class QMFEventClass extends QMFClass +public class JsonConfigurationStoreFactory implements ConfigurationStoreFactory { - public QMFEventClass(String name, - byte[] schemaHash, - List<QMFProperty> properties, - List<QMFStatistic> statistics, List<QMFMethod> methods) + @Override + public ConfigurationEntryStore createStore() { - super(Type.EVENT, name, schemaHash, properties, statistics, methods); + return new JsonConfigurationEntryStore(); } - public QMFEventClass(String name, byte[] schemaHash) + @Override + public String getStoreType() { - super(Type.EVENT, name, schemaHash); + return JsonConfigurationEntryStore.STORE_TYPE; } - abstract public QMFEventSeverity getSeverity(); - -}
\ No newline at end of file +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java new file mode 100644 index 0000000000..b6de1e136a --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/ChangeStateTask.java @@ -0,0 +1,67 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.updater; + +import java.util.concurrent.Callable; + +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; + +public final class ChangeStateTask implements Callable<State> +{ + private ConfiguredObject _object; + private State _expectedState; + private State _desiredState; + + public ChangeStateTask(ConfiguredObject object, State expectedState, State desiredState) + { + _object = object; + _expectedState = expectedState; + _desiredState = desiredState; + } + + public ConfiguredObject getObject() + { + return _object; + } + + public State getExpectedState() + { + return _expectedState; + } + + public State getDesiredState() + { + return _desiredState; + } + + @Override + public State call() + { + return _object.setDesiredState(_expectedState, _desiredState); + } + + @Override + public String toString() + { + return "ChangeStateTask [object=" + _object + ", expectedState=" + _expectedState + ", desiredState=" + _desiredState + "]"; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java new file mode 100644 index 0000000000..d3a8f5b797 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/CreateChildTask.java @@ -0,0 +1,78 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.updater; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Callable; + +import org.apache.qpid.server.model.ConfiguredObject; + +public final class CreateChildTask implements Callable<ConfiguredObject> +{ + private ConfiguredObject _object; + private Class<? extends ConfiguredObject> _childClass; + private Map<String, Object> _attributes; + private ConfiguredObject[] _otherParents; + + public CreateChildTask(ConfiguredObject object, Class<? extends ConfiguredObject> childClass, Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + _object = object; + _childClass = childClass; + _attributes = attributes; + _otherParents = otherParents; + } + + public ConfiguredObject getObject() + { + return _object; + } + + public Class<? extends ConfiguredObject> getChildClass() + { + return _childClass; + } + + public Map<String, Object> getAttributes() + { + return _attributes; + } + + public ConfiguredObject[] getOtherParents() + { + return _otherParents; + } + + @Override + public ConfiguredObject call() + { + return _object.createChild(_childClass, _attributes, _otherParents); + } + + @Override + public String toString() + { + return "CreateChildTask [object=" + _object + ", childClass=" + _childClass + ", attributes=" + _attributes + + ", otherParents=" + Arrays.toString(_otherParents) + "]"; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java new file mode 100644 index 0000000000..94649434e6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/SetAttributeTask.java @@ -0,0 +1,74 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.updater; + +import java.util.concurrent.Callable; + +import org.apache.qpid.server.model.ConfiguredObject; + +public final class SetAttributeTask implements Callable<Object> +{ + private ConfiguredObject _object; + private String _attributeName; + private Object _expectedValue; + private Object _desiredValue; + + public SetAttributeTask(ConfiguredObject object, String attributeName, Object expectedValue, Object desiredValue) + { + _object = object; + _attributeName = attributeName; + _expectedValue = expectedValue; + _desiredValue = desiredValue; + } + + public ConfiguredObject getObject() + { + return _object; + } + + public String getAttributeName() + { + return _attributeName; + } + + public Object getExpectedValue() + { + return _expectedValue; + } + + public Object getDesiredValue() + { + return _desiredValue; + } + + @Override + public Object call() + { + return _object.setAttribute(_attributeName, _expectedValue, _desiredValue); + } + + @Override + public String toString() + { + return "SetAttributeTask [object=" + _object + ", attributeName=" + _attributeName + ", expectedValue=" + _expectedValue + + ", desiredValue=" + _desiredValue + "]"; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java new file mode 100644 index 0000000000..671104d413 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java @@ -0,0 +1,324 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.updater; + +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import javax.security.auth.Subject; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.security.SecurityManager; + +public class TaskExecutor +{ + private static final String TASK_EXECUTION_THREAD_NAME = "Broker-Configuration-Thread"; + private static final Logger LOGGER = Logger.getLogger(TaskExecutor.class); + + private volatile Thread _taskThread; + private final AtomicReference<State> _state; + private volatile ExecutorService _executor; + + public TaskExecutor() + { + _state = new AtomicReference<State>(State.INITIALISING); + } + + public State getState() + { + return _state.get(); + } + + public void start() + { + if (_state.compareAndSet(State.INITIALISING, State.ACTIVE)) + { + LOGGER.debug("Starting task executor"); + _executor = Executors.newFixedThreadPool(1, new ThreadFactory() + { + @Override + public Thread newThread(Runnable r) + { + _taskThread = new Thread(r, TASK_EXECUTION_THREAD_NAME); + return _taskThread; + } + }); + LOGGER.debug("Task executor is started"); + } + } + + public void stopImmediately() + { + if (_state.compareAndSet(State.ACTIVE, State.STOPPED)) + { + ExecutorService executor = _executor; + if (executor != null) + { + LOGGER.debug("Stopping task executor immediately"); + List<Runnable> cancelledTasks = executor.shutdownNow(); + if (cancelledTasks != null) + { + for (Runnable runnable : cancelledTasks) + { + if (runnable instanceof RunnableFuture<?>) + { + ((RunnableFuture<?>) runnable).cancel(true); + } + } + } + _executor = null; + _taskThread = null; + LOGGER.debug("Task executor was stopped immediately. Number of unfinished tasks: " + cancelledTasks.size()); + } + } + } + + public void stop() + { + if (_state.compareAndSet(State.ACTIVE, State.STOPPED)) + { + ExecutorService executor = _executor; + if (executor != null) + { + LOGGER.debug("Stopping task executor"); + executor.shutdown(); + _executor = null; + _taskThread = null; + LOGGER.debug("Task executor is stopped"); + } + } + } + + Future<?> submit(Callable<?> task) + { + checkState(); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Submitting task: " + task); + } + Future<?> future = null; + if (isTaskExecutorThread()) + { + Object result = executeTaskAndHandleExceptions(task); + return new ImmediateFuture(result); + } + else + { + future = _executor.submit(new CallableWrapper(task)); + } + return future; + } + + public Object submitAndWait(Callable<?> task) throws CancellationException + { + try + { + Future<?> future = submit(task); + return future.get(); + } + catch (InterruptedException e) + { + throw new RuntimeException("Task execution was interrupted: " + task, e); + } + catch (ExecutionException e) + { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) + { + throw (RuntimeException) cause; + } + else if (cause instanceof Exception) + { + throw new RuntimeException("Failed to execute user task: " + task, cause); + } + else if (cause instanceof Error) + { + throw (Error) cause; + } + else + { + throw new RuntimeException("Failed to execute user task: " + task, cause); + } + } + } + + public boolean isTaskExecutorThread() + { + return Thread.currentThread() == _taskThread; + } + + private void checkState() + { + if (_state.get() != State.ACTIVE) + { + throw new IllegalStateException("Task executor is not in ACTIVE state"); + } + } + + private Object executeTaskAndHandleExceptions(Callable<?> userTask) + { + try + { + return executeTask(userTask); + } + catch (Exception e) + { + if (e instanceof RuntimeException) + { + throw (RuntimeException) e; + } + throw new RuntimeException("Failed to execute user task: " + userTask, e); + } + } + + private Object executeTask(Callable<?> userTask) throws Exception + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Performing task " + userTask); + } + Object result = userTask.call(); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Task " + userTask + " is performed successfully with result:" + result); + } + return result; + } + + private class CallableWrapper implements Callable<Object> + { + private Callable<?> _userTask; + private Subject _securityManagerSubject; + private LogActor _actor; + private Subject _contextSubject; + + public CallableWrapper(Callable<?> userWork) + { + _userTask = userWork; + _securityManagerSubject = SecurityManager.getThreadSubject(); + _actor = CurrentActor.get(); + _contextSubject = Subject.getSubject(AccessController.getContext()); + } + + @Override + public Object call() throws Exception + { + SecurityManager.setThreadSubject(_securityManagerSubject); + CurrentActor.set(_actor); + + try + { + Object result = null; + try + { + result = Subject.doAs(_contextSubject, new PrivilegedExceptionAction<Object>() + { + @Override + public Object run() throws Exception + { + return executeTask(_userTask); + } + }); + } + catch (PrivilegedActionException e) + { + throw e.getException(); + } + return result; + } + finally + { + try + { + CurrentActor.remove(); + } + catch (Exception e) + { + LOGGER.warn("Unxpected exception on current actor removal", e); + } + try + { + SecurityManager.setThreadSubject(null); + } + catch (Exception e) + { + LOGGER.warn("Unxpected exception on nullifying of subject for a security manager", e); + } + } + } + } + + private class ImmediateFuture implements Future<Object> + { + private Object _result; + + public ImmediateFuture(Object result) + { + super(); + this._result = result; + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) + { + return false; + } + + @Override + public boolean isCancelled() + { + return false; + } + + @Override + public boolean isDone() + { + return true; + } + + @Override + public Object get() + { + return _result; + } + + @Override + public Object get(long timeout, TimeUnit unit) + { + return get(); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java index 512a8c6996..246e056f0b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java @@ -23,14 +23,12 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ExchangeConfigType; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.ExchangeMessages; import org.apache.qpid.server.logging.subjects.ExchangeLogSubject; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueRegistry; @@ -86,8 +84,6 @@ public abstract class AbstractExchange implements Exchange //TODO : persist creation time private long _createTime = System.currentTimeMillis(); - private UUID _qmfId; - public AbstractExchange(final ExchangeType<? extends Exchange> type) { _type = type; @@ -113,19 +109,12 @@ public abstract class AbstractExchange implements Exchange _ticket = ticket; _id = id; - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); _logSubject = new ExchangeLogSubject(this, this.getVirtualHost()); // Log Exchange creation CurrentActor.get().message(ExchangeMessages.CREATED(String.valueOf(getTypeShortString()), String.valueOf(name), durable)); } - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - public boolean isDurable() { return _durable; @@ -146,7 +135,6 @@ public abstract class AbstractExchange implements Exchange if(_closed.compareAndSet(false,true)) { - getConfigStore().removeConfiguredObject(this); if(_alternateExchange != null) { _alternateExchange.removeReference(this); @@ -298,29 +286,11 @@ public abstract class AbstractExchange implements Exchange return _id; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ExchangeConfigType getConfigType() - { - return ExchangeConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _virtualHost; - } - public long getBindingCount() { return getBindings().size(); } - - public final List<? extends BaseQueue> route(final InboundMessage message) { _receivedMessageCount.incrementAndGet(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java index 5058f91995..5e6e36d330 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java @@ -27,10 +27,9 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.AMQUnknownExchangeType; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.qmf.ManagementExchange; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.virtualhost.VirtualHost; import java.util.ArrayList; @@ -41,42 +40,72 @@ import java.util.UUID; public class DefaultExchangeFactory implements ExchangeFactory { - private static final Logger _logger = Logger.getLogger(DefaultExchangeFactory.class); public static final String DEFAULT_DLE_NAME_SUFFIX = "_DLE"; - private Map<AMQShortString, ExchangeType<? extends Exchange>> _exchangeClassMap = new HashMap<AMQShortString, ExchangeType<? extends Exchange>>(); + private static final Logger LOGGER = Logger.getLogger(DefaultExchangeFactory.class); + + private static final AMQShortString[] BASE_EXCHANGE_TYPES = + new AMQShortString[]{ExchangeDefaults.DIRECT_EXCHANGE_CLASS, + ExchangeDefaults.FANOUT_EXCHANGE_CLASS, + ExchangeDefaults.HEADERS_EXCHANGE_CLASS, + ExchangeDefaults.TOPIC_EXCHANGE_CLASS}; + private final VirtualHost _host; + private Map<AMQShortString, ExchangeType<? extends Exchange>> _exchangeClassMap = new HashMap<AMQShortString, ExchangeType<? extends Exchange>>(); public DefaultExchangeFactory(VirtualHost host) { _host = host; - registerExchangeType(DirectExchange.TYPE); - registerExchangeType(TopicExchange.TYPE); - registerExchangeType(HeadersExchange.TYPE); - registerExchangeType(FanoutExchange.TYPE); - registerExchangeType(ManagementExchange.TYPE); + + @SuppressWarnings("rawtypes") + Iterable<ExchangeType> exchangeTypes = loadExchangeTypes(); + for (ExchangeType<?> exchangeType : exchangeTypes) + { + AMQShortString typeName = exchangeType.getName(); + + if(LOGGER.isDebugEnabled()) + { + LOGGER.debug("Registering exchange type '" + typeName + "' using class '" + exchangeType.getClass().getName() + "'"); + } + + if(_exchangeClassMap.containsKey(typeName)) + { + ExchangeType<?> existingType = _exchangeClassMap.get(typeName); + + throw new IllegalStateException("ExchangeType with type name '" + typeName + "' is already registered using class '" + + existingType.getClass().getName() + "', can not register class '" + + exchangeType.getClass().getName() + "'"); + } + + _exchangeClassMap.put(typeName, exchangeType); + } + + for(AMQShortString type : BASE_EXCHANGE_TYPES) + { + if(!_exchangeClassMap.containsKey(type)) + { + throw new IllegalStateException("Did not find expected exchange type: " + type.asString()); + } + } } - public void registerExchangeType(ExchangeType<? extends Exchange> type) + @SuppressWarnings("rawtypes") + protected Iterable<ExchangeType> loadExchangeTypes() { - _exchangeClassMap.put(type.getName(), type); + return new QpidServiceLoader<ExchangeType>().atLeastOneInstanceOf(ExchangeType.class); } public Collection<ExchangeType<? extends Exchange>> getRegisteredTypes() { return _exchangeClassMap.values(); } - + public Collection<ExchangeType<? extends Exchange>> getPublicCreatableTypes() { Collection<ExchangeType<? extends Exchange>> publicTypes = new ArrayList<ExchangeType<? extends Exchange>>(); publicTypes.addAll(_exchangeClassMap.values()); - //Remove the ManagementExchange type if present, as these - //are private and cannot be created by external means - publicTypes.remove(ManagementExchange.TYPE); - return publicTypes; } @@ -120,42 +149,4 @@ public class DefaultExchangeFactory implements ExchangeFactory Exchange e = exchType.newInstance(id, _host, exchange, durable, ticket, autoDelete); return e; } - - public void initialise(VirtualHostConfiguration hostConfig) - { - - if (hostConfig == null) - { - return; - } - - for(Object className : hostConfig.getCustomExchanges()) - { - try - { - ExchangeType<?> exchangeType = ApplicationRegistry.getInstance().getPluginManager().getExchanges().get(String.valueOf(className)); - if (exchangeType == null) - { - _logger.error("No such custom exchange class found: \""+String.valueOf(className)+"\""); - continue; - } - Class<? extends ExchangeType> exchangeTypeClass = exchangeType.getClass(); - ExchangeType<? extends ExchangeType> type = exchangeTypeClass.newInstance(); - registerExchangeType(type); - } - catch (ClassCastException classCastEx) - { - _logger.error("No custom exchange class: \""+String.valueOf(className)+"\" cannot be registered as it does not extend class \""+ExchangeType.class+"\""); - } - catch (IllegalAccessException e) - { - _logger.error("Cannot create custom exchange class: \""+String.valueOf(className)+"\"",e); - } - catch (InstantiationException e) - { - _logger.error("Cannot create custom exchange class: \""+String.valueOf(className)+"\"",e); - } - } - - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java index 07813b073b..9cce8d640b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java @@ -26,6 +26,7 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.virtualhost.VirtualHost; diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java index 92326412c1..fc6ce15bc4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java @@ -20,30 +20,22 @@ */ package org.apache.qpid.server.exchange; -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import javax.management.JMException; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; public class DirectExchange extends AbstractExchange { - private static final Logger _logger = Logger.getLogger(DirectExchange.class); - private static final class BindingSet { private CopyOnWriteArraySet<Binding> _bindings = new CopyOnWriteArraySet<Binding>(); @@ -55,7 +47,6 @@ public class DirectExchange extends AbstractExchange recalculateQueues(); } - public synchronized void removeBinding(Binding binding) { _bindings.remove(binding); @@ -91,36 +82,7 @@ public class DirectExchange extends AbstractExchange private final ConcurrentHashMap<String, BindingSet> _bindingsByKey = new ConcurrentHashMap<String, BindingSet>(); - public static final ExchangeType<DirectExchange> TYPE = new ExchangeType<DirectExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.DIRECT_EXCHANGE_CLASS; - } - - public Class<DirectExchange> getExchangeClass() - { - return DirectExchange.class; - } - - public DirectExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - DirectExchange exch = new DirectExchange(); - exch.initialise(id, host,name,durable,ticket,autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return ExchangeDefaults.DIRECT_EXCHANGE_NAME; - } - }; - + public static final ExchangeType<DirectExchange> TYPE = new DirectExchangeType(); public DirectExchange() { diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java new file mode 100644 index 0000000000..096d5265ed --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchangeType.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.exchange; + +import java.util.UUID; + +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class DirectExchangeType implements ExchangeType<DirectExchange> +{ + public AMQShortString getName() + { + return ExchangeDefaults.DIRECT_EXCHANGE_CLASS; + } + + public DirectExchange newInstance(UUID id, VirtualHost host, + AMQShortString name, + boolean durable, + int ticket, + boolean autoDelete) throws AMQException + { + DirectExchange exch = new DirectExchange(); + exch.initialise(id, host,name,durable,ticket,autoDelete); + return exch; + } + + public AMQShortString getDefaultExchangeName() + { + return ExchangeDefaults.DIRECT_EXCHANGE_NAME; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java index 762686e68d..4bafb04c33 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java @@ -26,8 +26,8 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ExchangeConfig; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -38,9 +38,23 @@ import java.util.List; import java.util.Map; import java.util.UUID; -public interface Exchange extends ExchangeReferrer, ExchangeConfig +public interface Exchange extends ExchangeReferrer { + String getName(); + + ExchangeType getType(); + + long getBindingCount(); + + long getByteDrops(); + + long getByteReceives(); + + long getMsgDrops(); + + long getMsgReceives(); + public interface BindingListener { void bindingAdded(Exchange exchange, Binding binding); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java index aae4ae89bb..e602d476d9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.plugin.ExchangeType; import java.util.Collection; import java.util.UUID; @@ -34,8 +34,6 @@ public interface ExchangeFactory int ticket) throws AMQException; - void initialise(VirtualHostConfiguration hostConfig); - Collection<ExchangeType<? extends Exchange>> getRegisteredTypes(); Collection<ExchangeType<? extends Exchange>> getPublicCreatableTypes(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java index ba4f57a8e0..edb476f3aa 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeInitialiser.java @@ -24,6 +24,7 @@ package org.apache.qpid.server.exchange; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.store.DurableConfigurationStore; public class ExchangeInitialiser diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java index 5f4998f77f..8c433ce985 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java @@ -22,19 +22,15 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import javax.management.JMException; import java.util.ArrayList; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public class FanoutExchange extends AbstractExchange @@ -48,35 +44,7 @@ public class FanoutExchange extends AbstractExchange */ private final ConcurrentHashMap<AMQQueue,Integer> _queues = new ConcurrentHashMap<AMQQueue,Integer>(); - public static final ExchangeType<FanoutExchange> TYPE = new ExchangeType<FanoutExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.FANOUT_EXCHANGE_CLASS; - } - - public Class<FanoutExchange> getExchangeClass() - { - return FanoutExchange.class; - } - - public FanoutExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - FanoutExchange exch = new FanoutExchange(); - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return ExchangeDefaults.FANOUT_EXCHANGE_NAME; - } - }; + public static final ExchangeType<FanoutExchange> TYPE = new FanoutExchangeType(); public FanoutExchange() { diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java index 34b2a851dc..0371a363de 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFBrokerResponseCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchangeType.java @@ -18,28 +18,34 @@ * under the License. * */ +package org.apache.qpid.server.exchange; -package org.apache.qpid.qmf; +import java.util.UUID; +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBEncoder; -public class QMFBrokerResponseCommand extends QMFCommand +public class FanoutExchangeType implements ExchangeType<FanoutExchange> { - private QMFCommandHeader _header; - private VirtualHost _virtualHost; + public AMQShortString getName() + { + return ExchangeDefaults.FANOUT_EXCHANGE_CLASS; + } - public QMFBrokerResponseCommand(QMFBrokerRequestCommand qmfBrokerRequestCommand, VirtualHost virtualHost) + public FanoutExchange newInstance(UUID id, VirtualHost host, AMQShortString name, + boolean durable, int ticket, boolean autoDelete) + throws AMQException { - super( new QMFCommandHeader(qmfBrokerRequestCommand.getHeader().getVersion(), - qmfBrokerRequestCommand.getHeader().getSeq(), - QMFOperation.BROKER_RESPONSE)); - _virtualHost = virtualHost; + FanoutExchange exch = new FanoutExchange(); + exch.initialise(id, host, name, durable, ticket, autoDelete); + return exch; } - public void encode(BBEncoder encoder) + public AMQShortString getDefaultExchangeName() { - super.encode(encoder); - encoder.writeUuid(_virtualHost.getBrokerId()); + return ExchangeDefaults.FANOUT_EXCHANGE_NAME; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java index 6bad59c2ae..746c8ac6bc 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java @@ -22,22 +22,18 @@ package org.apache.qpid.server.exchange; import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import javax.management.JMException; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; @@ -81,40 +77,12 @@ public class HeadersExchange extends AbstractExchange new CopyOnWriteArrayList<HeadersBinding>(); - public static final ExchangeType<HeadersExchange> TYPE = new ExchangeType<HeadersExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.HEADERS_EXCHANGE_CLASS; - } - - public Class<HeadersExchange> getExchangeClass() - { - return HeadersExchange.class; - } - - public HeadersExchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, - boolean autoDelete) throws AMQException - { - HeadersExchange exch = new HeadersExchange(); - - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - - return ExchangeDefaults.HEADERS_EXCHANGE_NAME; - } - }; + public static final ExchangeType<HeadersExchange> TYPE = new HeadersExchangeType(); public HeadersExchange() { super(TYPE); } - public ArrayList<BaseQueue> doRoute(InboundMessage payload) diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java index 191f8041d2..ed4d57d0f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostHouseKeepingPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchangeType.java @@ -18,44 +18,35 @@ * under the License. * */ -package org.apache.qpid.server.virtualhost.plugins; +package org.apache.qpid.server.exchange; -import org.apache.log4j.Logger; +import java.util.UUID; -import org.apache.qpid.server.virtualhost.HouseKeepingTask; +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.virtualhost.VirtualHost; -import java.util.concurrent.TimeUnit; - -public abstract class VirtualHostHouseKeepingPlugin extends HouseKeepingTask implements VirtualHostPlugin +public class HeadersExchangeType implements ExchangeType<HeadersExchange> { - private final Logger _logger = Logger.getLogger(getClass()); - - public VirtualHostHouseKeepingPlugin(VirtualHost vhost) + public AMQShortString getName() { - super(vhost); + return ExchangeDefaults.HEADERS_EXCHANGE_CLASS; } + public HeadersExchange newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, + boolean autoDelete) throws AMQException + { + HeadersExchange exch = new HeadersExchange(); - /** - * Long value representing the delay between repeats - * - * @return - */ - public abstract long getDelay(); - - /** - * Option to specify what the delay value represents - * - * @return - * - * @see java.util.concurrent.TimeUnit for valid value. - */ - public abstract TimeUnit getTimeUnit(); - + exch.initialise(id, host, name, durable, ticket, autoDelete); + return exch; + } - protected Logger getLogger() + public AMQShortString getDefaultExchangeName() { - return _logger; + + return ExchangeDefaults.HEADERS_EXCHANGE_NAME; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java index 0ce16bd3f7..6d548be508 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchange.java @@ -27,15 +27,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.UUID; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; -import javax.management.JMException; import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; import org.apache.qpid.AMQInvalidArgumentException; import org.apache.qpid.common.AMQPFilterTypes; -import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.filter.SelectorParsingException; import org.apache.qpid.filter.selector.ParseException; import org.apache.qpid.filter.selector.TokenMgrError; @@ -49,44 +45,15 @@ import org.apache.qpid.server.exchange.topic.TopicParser; import org.apache.qpid.server.filter.JMSSelectorFilter; import org.apache.qpid.server.filter.MessageFilter; import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.Filterable; -import org.apache.qpid.server.virtualhost.VirtualHost; public class TopicExchange extends AbstractExchange { - - public static final ExchangeType<TopicExchange> TYPE = new ExchangeType<TopicExchange>() - { - - public AMQShortString getName() - { - return ExchangeDefaults.TOPIC_EXCHANGE_CLASS; - } - - public Class<TopicExchange> getExchangeClass() - { - return TopicExchange.class; - } - - public TopicExchange newInstance(UUID id, VirtualHost host, - AMQShortString name, - boolean durable, - int ticket, - boolean autoDelete) throws AMQException - { - TopicExchange exch = new TopicExchange(); - exch.initialise(id, host, name, durable, ticket, autoDelete); - return exch; - } - - public AMQShortString getDefaultExchangeName() - { - return ExchangeDefaults.TOPIC_EXCHANGE_NAME; - } - }; + public static final ExchangeType<TopicExchange> TYPE = new TopicExchangeType(); private static final Logger _logger = Logger.getLogger(TopicExchange.class); @@ -291,7 +258,7 @@ public class TopicExchange extends AbstractExchange public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue) { - Binding binding = new Binding(null, null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments)); + Binding binding = new Binding(null, routingKey.toString(), queue, this, FieldTable.convertToMap(arguments)); if (arguments == null) { @@ -314,7 +281,7 @@ public class TopicExchange extends AbstractExchange public boolean isBound(String bindingKey, Map<String, Object> arguments, AMQQueue queue) { - Binding binding = new Binding(null, null, bindingKey, queue, this, arguments); + Binding binding = new Binding(null, bindingKey, queue, this, arguments); if (arguments == null) { return _bindings.containsKey(binding); diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java new file mode 100644 index 0000000000..25a3549e61 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/TopicExchangeType.java @@ -0,0 +1,53 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.exchange; + +import java.util.UUID; + +import org.apache.qpid.AMQException; +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.plugin.ExchangeType; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class TopicExchangeType implements ExchangeType<TopicExchange> +{ + public AMQShortString getName() + { + return ExchangeDefaults.TOPIC_EXCHANGE_CLASS; + } + + public TopicExchange newInstance(UUID id, VirtualHost host, + AMQShortString name, + boolean durable, + int ticket, + boolean autoDelete) throws AMQException + { + TopicExchange exch = new TopicExchange(); + exch.initialise(id, host, name, durable, ticket, autoDelete); + return exch; + } + + public AMQShortString getDefaultExchangeName() + { + return ExchangeDefaults.TOPIC_EXCHANGE_NAME; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java deleted file mode 100644 index 7eb476b15a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java +++ /dev/null @@ -1,913 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.federation; - -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQStoreException; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.BridgeConfig; -import org.apache.qpid.server.configuration.BridgeConfigType; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.flow.FlowCreditManager_0_10; -import org.apache.qpid.server.flow.WindowCreditManager; -import org.apache.qpid.server.message.MessageMetaData_0_10; -import org.apache.qpid.server.message.MessageTransferMessage; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.queue.BaseQueue; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.StoredMessage; -import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; -import org.apache.qpid.server.subscription.Subscription_0_10; -import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.txn.AutoCommitTransaction; -import org.apache.qpid.server.txn.ServerTransaction; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.DeliveryProperties; -import org.apache.qpid.transport.MessageAcceptMode; -import org.apache.qpid.transport.MessageAcquireMode; -import org.apache.qpid.transport.MessageCreditUnit; -import org.apache.qpid.transport.MessageFlowMode; -import org.apache.qpid.transport.MessageReject; -import org.apache.qpid.transport.MessageRejectCode; -import org.apache.qpid.transport.MessageTransfer; -import org.apache.qpid.transport.Option; -import org.apache.qpid.transport.RangeSet; -import org.apache.qpid.transport.RangeSetFactory; -import org.apache.qpid.transport.Session; -import org.apache.qpid.transport.SessionException; -import org.apache.qpid.transport.SessionListener; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -public class Bridge implements BridgeConfig -{ - private static final String DURABLE = "durable"; - private static final String DYNAMIC = "dynamic"; - private static final String SRC_IS_QUEUE = "srcIsQueue"; - private static final String SRC_IS_LOCAL = "srcIsLocal"; - private static final String SOURCE = "source"; - private static final String DESTINATION = "destination"; - private static final String KEY = "key"; - private static final String TAG = "tag"; - private static final String EXCLUDES = "excludes"; - private final boolean _durable; - private final boolean _dynamic; - private final boolean _queueBridge; - private final boolean _localSource; - private final String _source; - private final String _destination; - private final String _key; - private final String _tag; - private final String _excludes; - private final BrokerLink _link; - private UUID _qmfId; - private long _createTime = System.currentTimeMillis(); - - private Session _session; - - private BridgeImpl _delegate; - - private final int _bridgeNo; - private AutoCommitTransaction _transaction; - - public Bridge(final BrokerLink brokerLink, - final int bridgeNo, - final boolean durable, - final boolean dynamic, - final boolean srcIsQueue, - final boolean srcIsLocal, - final String src, - final String dest, - final String key, - final String tag, - final String excludes) - { - _link = brokerLink; - _bridgeNo = bridgeNo; - _durable = durable; - _dynamic = dynamic; - _queueBridge = srcIsQueue; - _localSource = srcIsLocal; - _source = src; - _destination = dest; - _key = key; - _tag = tag; - _excludes = excludes; - _qmfId = durable ? brokerLink.getConfigStore().createPersistentId() : brokerLink.getConfigStore().createId(); - - _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore()); - - if(durable) - { - try - { - brokerLink.getVirtualHost().getMessageStore().createBridge(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - - createDelegate(); - } - - private void createDelegate() - { - if(_dynamic) - { - if(_localSource) - { - // TODO - } - else - { - if(_queueBridge) - { - // TODO - } - else - { - _delegate = new DynamicExchangeBridge(); - } - } - } - else - { - if(_localSource) - { - if(_queueBridge) - { - _delegate = new StaticQueuePushBridge(); - } - else - { - _delegate = new StaticExchangePushBridge(); - } - } - else - { - if(_queueBridge) - { - _delegate = new StaticQueuePullBridge(); - } - else - { - _delegate = new StaticExchangePullBridge(); - } - } - } - } - - public Bridge(final BrokerLink brokerLink, - final int bridgeNo, - final UUID id, - final long createTime, - final Map<String, String> arguments) - { - _link = brokerLink; - _bridgeNo = bridgeNo; - _qmfId = id; - brokerLink.getConfigStore().persistentIdInUse(id); - _createTime = createTime; - - _durable = Boolean.valueOf(arguments.get(DURABLE)); - _dynamic = Boolean.valueOf(arguments.get(DYNAMIC)); - _queueBridge = Boolean.valueOf(arguments.get(SRC_IS_QUEUE)); - _localSource = Boolean.valueOf(arguments.get(SRC_IS_LOCAL)); - _source = arguments.get(SOURCE); - _destination = arguments.get(DESTINATION); - _key = arguments.get(KEY); - _tag = arguments.get(TAG); - _excludes = arguments.get(EXCLUDES); - - //TODO. - _transaction = new AutoCommitTransaction(getVirtualHost().getMessageStore()); - - - if(_durable) - { - try - { - brokerLink.getVirtualHost().getMessageStore().createBridge(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - - createDelegate(); - } - - - public Map<String,String> getArguments() - { - Map<String,String> arguments = new HashMap<String, String>(); - - arguments.put(DURABLE, String.valueOf(_durable)); - arguments.put(DYNAMIC, String.valueOf(_dynamic)); - arguments.put(SRC_IS_QUEUE, String.valueOf(_queueBridge)); - arguments.put(SRC_IS_LOCAL, String.valueOf(_localSource)); - arguments.put(SOURCE, _source); - arguments.put(DESTINATION, _destination); - arguments.put(KEY, _key); - arguments.put(TAG, _tag); - arguments.put(EXCLUDES, _excludes); - - return Collections.unmodifiableMap(arguments); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public BridgeConfigType getConfigType() - { - return BridgeConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getLink(); - } - - public boolean isDurable() - { - return _durable; - } - - public boolean isDynamic() - { - return _dynamic; - } - - public boolean isQueueBridge() - { - return _queueBridge; - } - - public boolean isLocalSource() - { - return _localSource; - } - - public String getSource() - { - return _source; - } - - public String getDestination() - { - return _destination; - } - - public String getKey() - { - return _key; - } - - public String getTag() - { - return _tag; - } - - public String getExcludes() - { - return _excludes; - } - - public BrokerLink getLink() - { - return _link; - } - - public Integer getChannelId() - { - return (_session == null) ? 0 : _session.getChannel(); - } - - public int getAckBatching() - { - return 0; - } - - public long getCreateTime() - { - return _createTime; - } - - @Override - public boolean equals(final Object o) - { - if (this == o) - { - return true; - } - if (o == null || getClass() != o.getClass()) - { - return false; - } - - final Bridge bridge = (Bridge) o; - - if (_durable != bridge._durable) - { - return false; - } - if (_dynamic != bridge._dynamic) - { - return false; - } - if (_localSource != bridge._localSource) - { - return false; - } - if (_queueBridge != bridge._queueBridge) - { - return false; - } - if (_destination != null ? !_destination.equals(bridge._destination) : bridge._destination != null) - { - return false; - } - if (_excludes != null ? !_excludes.equals(bridge._excludes) : bridge._excludes != null) - { - return false; - } - if (_key != null ? !_key.equals(bridge._key) : bridge._key != null) - { - return false; - } - if (_source != null ? !_source.equals(bridge._source) : bridge._source != null) - { - return false; - } - if (_tag != null ? !_tag.equals(bridge._tag) : bridge._tag != null) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int result = (_durable ? 1 : 0); - result = 31 * result + (_dynamic ? 1 : 0); - result = 31 * result + (_queueBridge ? 1 : 0); - result = 31 * result + (_localSource ? 1 : 0); - result = 31 * result + (_source != null ? _source.hashCode() : 0); - result = 31 * result + (_destination != null ? _destination.hashCode() : 0); - result = 31 * result + (_key != null ? _key.hashCode() : 0); - result = 31 * result + (_tag != null ? _tag.hashCode() : 0); - result = 31 * result + (_excludes != null ? _excludes.hashCode() : 0); - return result; - } - - public void setSession(final Session session) - { - _session = session; - _delegate.setSession(session); - } - - private long getMessageWindowSize() - { - return 10l; - } - - - VirtualHost getVirtualHost() - { - return _link.getVirtualHost(); - } - - public void close() - { - // TODO - _delegate.close(); - _session = null; - } - - - - private interface BridgeImpl - { - void setSession(Session session); - - void close(); - } - - private abstract class AbstractPullBridge implements BridgeImpl, SessionListener - { - public final void setSession(final Session session) - { - session.setSessionListener(this); - onSession(); - - } - - abstract void onSession(); - - - - public void message(final Session ssn, final MessageTransfer xfr) - { - ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - - Exchange exchange = exchangeRegistry.getExchange(_destination); - - // TODO - deal with exchange not existing - - DeliveryProperties delvProps = null; - if(xfr.getHeader() != null && (delvProps = xfr.getHeader().getDeliveryProperties()) != null && delvProps.hasTtl() && - !delvProps.hasExpiration()) - { - delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl()); - } - - MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr); - final MessageStore store = getVirtualHost().getMessageStore(); - StoredMessage<MessageMetaData_0_10> storeMessage = store.addMessage(messageMetaData); - storeMessage.addContent(0,xfr.getBody()); - storeMessage.flushToStore(); - MessageTransferMessage message = new MessageTransferMessage(storeMessage, ((ServerSession)_session).getReference()); - - List<? extends BaseQueue> queues = exchange.route(message); - - - - if(queues != null && queues.size() != 0) - { - enqueue(message, queues); - } - else - { - if(delvProps == null || !delvProps.hasDiscardUnroutable() || !delvProps.getDiscardUnroutable()) - { - if(xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT) - { - RangeSet rejects = RangeSetFactory.createRangeSet(); - rejects.add(xfr.getId()); - MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable"); - ssn.invoke(reject); - } - else - { - Exchange alternate = exchange.getAlternateExchange(); - if(alternate != null) - { - queues = alternate.route(message); - if(queues != null && queues.size() != 0) - { - enqueue(message, queues); - } - else - { - //TODO - log the message discard - } - } - else - { - //TODO - log the message discard - } - - - } - } - - - } - - ssn.processed(xfr); - - } - - - private void enqueue(final ServerMessage message, final List<? extends BaseQueue> queues) - { - _transaction.enqueue(queues,message, new ServerTransaction.Action() - { - - private BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]); - - public void postCommit() - { - for(int i = 0; i < _queues.length; i++) - { - try - { - _queues[i].enqueue(message); - } - catch (AMQException e) - { - // TODO - - throw new RuntimeException(e); - } - } - } - - public void onRollback() - { - // NO-OP - } - }, 0L); - } - - public void exception(final Session session, final SessionException exception) - { - // TODO - Handle exceptions - } - - public void closed(final Session session) - { - // TODO - handle close - } - - public void opened(final Session session) - { - // this method never called - } - - public void resumed(final Session session) - { - // will never resume these sessions - } - - - - } - - private final class StaticExchangePullBridge extends AbstractPullBridge - { - private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag();; - - public void onSession() - { - - final HashMap<String, Object> options = new HashMap<String, Object>(); - options.put("qpid.trace.exclude", _link.getFederationTag()); - options.put("qpid.trace.id",_link.getRemoteFederationTag()); - _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE); - _session.sync(); - // todo check exception - final Map<String,Object> bindingArgs = new HashMap<String,Object>(); - _session.exchangeBind(_tmpQueueName, _source, _key, bindingArgs); - _session.sync(); - // todo check exception - - final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP; - final String subName = String.valueOf(_bridgeNo); - _session.messageSubscribe(_tmpQueueName, - subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions); - _session.sync(); - // todo check exception - - _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW); - _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize()); - _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF); - - } - - public void close() - { - // TODO - } - } - - private final class StaticQueuePullBridge extends AbstractPullBridge - { - - public void onSession() - { - - final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP; - final String subName = String.valueOf(_bridgeNo); - _session.messageSubscribe(_source, - subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions); - _session.sync(); - // todo check exception - - _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW); - _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize()); - _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF); - - } - - public void close() - { - // TODO - } - } - - private final class DynamicExchangeBridge extends AbstractPullBridge implements Exchange.BindingListener - { - private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag(); - - private final ConcurrentMap<Binding,Binding> _bindings = new ConcurrentHashMap<Binding,Binding>(); - - - void onSession() - { - - - final HashMap<String, Object> options = new HashMap<String, Object>(); - options.put("qpid.trace.exclude", _link.getFederationTag()); - options.put("qpid.trace.id",_link.getRemoteFederationTag()); - _session.queueDeclare(_tmpQueueName,null, options, Option.AUTO_DELETE, Option.EXCLUSIVE); - _session.sync(); - // todo - check exception - - final Map<String,Object> subscribeOptions = Collections.EMPTY_MAP; - final String subName = String.valueOf(_bridgeNo); - _session.messageSubscribe(_tmpQueueName, - subName,MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0l, subscribeOptions); - _session.sync(); - // todo check exception - _session.messageSetFlowMode(subName,MessageFlowMode.WINDOW); - _session.messageFlow(subName, MessageCreditUnit.MESSAGE, getMessageWindowSize()); - _session.messageFlow(subName, MessageCreditUnit.BYTE, 0xFFFFFFFF); - _session.sync(); - // todo check exception - - - ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - - Exchange exchange = exchangeRegistry.getExchange(_destination); - - // TODO - check null - - exchange.addBindingListener(this); - - Collection<Binding> bindings = exchange.getBindings(); - for(Binding binding : bindings) - { - propogateBinding(binding); - } - - } - - private void propogateBinding(final Binding binding) - { - if(_bindings.putIfAbsent(binding,binding)== null) - { - Map<String,Object> arguments = new HashMap<String,Object>(binding.getArguments()); - - if(arguments.get("qpid.fed.origin") == null) - { - arguments.put("qpid.fed.op",""); - arguments.put("qpid.fed.origin",_link.getFederationTag()); - arguments.put("qpid.fed.tags",_link.getFederationTag()); - } - else - { - String tags = (String) arguments.get("qpid.fed.tags"); - if(tags == null) - { - tags = _link.getFederationTag(); - } - else - { - if(Arrays.asList(tags.split(",")).contains(_link.getFederationTag())) - { - return; - } - tags += "," + _link.getFederationTag(); - } - arguments.put("qpid.fed.tags", tags); - } - - _session.exchangeBind(_tmpQueueName, _source, binding.getBindingKey(), arguments); - _session.sync(); - // TODO - check exception? - - } - } - - private void propogateBindingRemoval(final Binding binding) - { - if(_bindings.remove(binding) != null) - { - // TODO - this is wrong!!!! - _session.exchangeUnbind(_tmpQueueName, _source, binding.getBindingKey()); - } - } - - - public void bindingAdded(final Exchange exchange, final Binding binding) - { - propogateBinding(binding); - } - - public void bindingRemoved(final Exchange exchange, final Binding binding) - { - propogateBindingRemoval(binding); - } - - public void close() - { - // TODO - } - } - - private class StaticExchangePushBridge implements BridgeImpl, SessionListener - { - private final String _tmpQueueName = "bridge_queue_" + _bridgeNo + "_" + _link.getFederationTag(); - private AMQQueue _queue; - - public void setSession(final Session session) - { - assert session instanceof ServerSession; - - session.setSessionListener(this); - - ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - - Exchange exchange = exchangeRegistry.getExchange(_source); - - // TODO - Check null - - final HashMap<String, Object> options = new HashMap<String, Object>(); - options.put("qpid.trace.exclude", _link.getFederationTag()); - options.put("qpid.trace.id",_link.getRemoteFederationTag()); - - try - { - _queue = AMQQueueFactory.createAMQQueueImpl(null, - _tmpQueueName, - isDurable(), - _link.getFederationTag(), - false, - false, - getVirtualHost(), options); - } - catch (AMQException e) - { - // TODO - throw new RuntimeException(e); - } - - FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize()); - - //TODO Handle the passing of non-null Filters and Arguments here - - Subscription_0_10 sub = SubscriptionFactoryImpl.INSTANCE.createSubscription((ServerSession)session, - _destination, - MessageAcceptMode.NONE, - MessageAcquireMode.PRE_ACQUIRED, - MessageFlowMode.WINDOW, - creditManager, null,null); - - ((ServerSession)session).register(_destination, sub); - - try - { - _queue.registerSubscription(sub, true); - getVirtualHost().getBindingFactory().addBinding(_key, _queue, exchange, Collections.<String, Object>emptyMap()); - } - catch (AMQException e) - { - // TODO - throw new RuntimeException(e); - } - } - - public void close() - { - // TODO - } - - public void opened(final Session session) - { - // this method never called - } - - public void resumed(final Session session) - { - // this session will never be resumed - } - - public void message(final Session ssn, final MessageTransfer xfr) - { - // messages should not be sent ... should probably log error - } - - public void exception(final Session session, final SessionException exception) - { - // TODO - } - - public void closed(final Session session) - { - // TODO - } - } - - private class StaticQueuePushBridge implements BridgeImpl, SessionListener - { - private AMQQueue _queue; - - public void setSession(final Session session) - { - assert session instanceof ServerSession; - - session.setSessionListener(this); - - QueueRegistry queueRegistry = getVirtualHost().getQueueRegistry(); - - _queue = queueRegistry.getQueue(_source); - - // TODO - null check - - FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize()); - - //TODO Handle the passing of non-null Filters and Arguments here - - Subscription_0_10 sub = SubscriptionFactoryImpl.INSTANCE.createSubscription((ServerSession)session, - _destination, - MessageAcceptMode.NONE, - MessageAcquireMode.PRE_ACQUIRED, - MessageFlowMode.WINDOW, - creditManager, null,null); - - ((ServerSession)session).register(_destination, sub); - - try - { - _queue.registerSubscription(sub, false); - } - catch (AMQException e) - { - // TODO - throw new RuntimeException(e); - } - - } - - public void close() - { - // TODO - } - - public void opened(final Session session) - { - // never called - } - - public void resumed(final Session session) - { - // session will not resume - } - - public void message(final Session ssn, final MessageTransfer xfr) - { - // should never be called ... should probably log error - } - - public void exception(final Session session, final SessionException exception) - { - // TODO - } - - public void closed(final Session session) - { - // TODO - } - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java deleted file mode 100644 index 1ef57c53cb..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java +++ /dev/null @@ -1,692 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.federation; - -import org.apache.qpid.AMQStoreException; -import org.apache.qpid.common.ServerPropertyNames; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.ConnectionConfigType; -import org.apache.qpid.server.configuration.LinkConfig; -import org.apache.qpid.server.configuration.LinkConfigType; -import org.apache.qpid.server.transport.ServerSession; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.Binary; -import org.apache.qpid.transport.ClientDelegate; -import org.apache.qpid.transport.Connection; -import org.apache.qpid.transport.ConnectionException; -import org.apache.qpid.transport.ConnectionListener; -import org.apache.qpid.transport.ConnectionSettings; -import org.apache.qpid.transport.Session; -import org.apache.qpid.transport.SessionDelegate; -import org.apache.qpid.transport.TransportException; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -public class BrokerLink implements LinkConfig, ConnectionListener -{ - - private static final int CORE_POOL_SIZE = 4; - - private static final ScheduledThreadPoolExecutor _threadPool = - new ScheduledThreadPoolExecutor(CORE_POOL_SIZE); - private static final String TRANSPORT = "transport"; - private static final String HOST = "host"; - private static final String PORT = "port"; - private static final String REMOTE_VHOST = "remoteVhost"; - private static final String DURABLE = "durable"; - private static final String AUTH_MECHANISM = "authMechanism"; - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - - - private final String _transport; - private final String _host; - private final int _port; - private final String _remoteVhost; - private final boolean _durable; - private final String _authMechanism; - private final String _username; - private final String _password; - private final VirtualHost _virtualHost; - private UUID _qmfId; - private AtomicBoolean _closing = new AtomicBoolean(); - private final long _createTime; - private Connection _qpidConnection; - private AtomicReference<Thread> _executor = new AtomicReference<Thread>(); - private AtomicInteger _bridgeId = new AtomicInteger(); - - private final ConcurrentHashMap<Bridge,Bridge> _bridges = new ConcurrentHashMap<Bridge,Bridge>(); - private final ConcurrentHashMap<Bridge,Bridge> _activeBridges = new ConcurrentHashMap<Bridge,Bridge>(); - private final ConcurrentLinkedQueue<Bridge> _pendingBridges = new ConcurrentLinkedQueue<Bridge>(); - private String _remoteFederationTag; - - private ConnectionConfig _connectionConfig; - private ConnectionException _exception; - private String _lastErrorMessage; - private int _retryDelay = 1; - private final Runnable _makeConnectionTask = new Runnable() - { - public void run() - { - doMakeConnection(); - } - }; - - - - - public static enum State - { - OPERATIONAL, - DOWN, - ESTABLISHING, - DELETED - } - - - private volatile State _state = State.DOWN; - - private static final AtomicReferenceFieldUpdater<BrokerLink, State> _stateUpdater = - AtomicReferenceFieldUpdater.newUpdater(BrokerLink.class, State.class, "_state"); - - private class ConnectionConfigAdapter implements ConnectionConfig - { - private long _adapterCreateTime = System.currentTimeMillis(); - private UUID _qmfId = BrokerLink.this.getConfigStore().createId(); - - public VirtualHost getVirtualHost() - { - return BrokerLink.this.getVirtualHost(); - } - - public String getAddress() - { - return _host+":"+_port; - } - - public Boolean isIncoming() - { - return false; - } - - public Boolean isSystemConnection() - { - return true; - } - - public Boolean isFederationLink() - { - return true; - } - - public String getAuthId() - { - return _username; - } - - public String getRemoteProcessName() - { - return null; - } - - public Integer getRemotePID() - { - return null; - } - - public Integer getRemoteParentPID() - { - return null; - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - - public boolean isDurable() - { - return false; - } - - public long getCreateTime() - { - return _adapterCreateTime; - } - - public Boolean isShadow() - { - return false; - } - - public void mgmtClose() - { - _connectionConfig.mgmtClose(); - } - } - - private class SessionFactory implements Connection.SessionFactory - { - - public Session newSession(final Connection conn, final Binary name, final long expiry) - { - return new ServerSession(conn, new SessionDelegate(), name, expiry, _connectionConfig); - } - }; - - public BrokerLink(final VirtualHost virtualHost, UUID qmfId, long createTime, Map<String, String> arguments) - { - _virtualHost = virtualHost; - _qmfId = qmfId; - virtualHost.getConfigStore().persistentIdInUse(qmfId); - _createTime = createTime; - _transport = arguments.get(TRANSPORT); - - _host = arguments.get(HOST); - _port = Integer.parseInt(arguments.get(PORT)); - _remoteVhost = arguments.get(REMOTE_VHOST); - _durable = Boolean.parseBoolean(arguments.get(DURABLE)); - _authMechanism = arguments.get("authMechanism"); - _username = arguments.get("username"); - _password = arguments.get("password"); - - if(_durable) - { - try - { - _virtualHost.getMessageStore().createBrokerLink(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - - - _qpidConnection = new Connection(); - _connectionConfig = new ConnectionConfigAdapter(); - _qpidConnection.addConnectionListener(this); - - - makeConnection(); - - } - - - public BrokerLink(final VirtualHost virtualHost, - final String transport, - final String host, - final int port, - final String remoteVhost, - final boolean durable, - final String authMechanism, - final String username, - final String password) - { - _virtualHost = virtualHost; - _transport = transport; - _createTime = System.currentTimeMillis(); - _host = host; - _port = port; - _remoteVhost = remoteVhost; - _durable = durable; - _authMechanism = authMechanism; - _username = username; - _password = password; - _qmfId = durable ? virtualHost.getConfigStore().createPersistentId() : virtualHost.getConfigStore().createId(); - - if(durable) - { - try - { - _virtualHost.getMessageStore().createBrokerLink(this); - } - catch (AMQStoreException e) - { - throw new RuntimeException(e); - } - } - _qpidConnection = new Connection(); - _connectionConfig = new ConnectionConfigAdapter(); - _qpidConnection.addConnectionListener(this); - - makeConnection(); - } - - public Map<String,String> getArguments() - { - Map<String,String> arguments = new HashMap<String, String>(); - - arguments.put(TRANSPORT, _transport); - arguments.put(HOST, _host); - arguments.put(PORT, String.valueOf(_port)); - arguments.put(REMOTE_VHOST, _remoteVhost); - arguments.put(DURABLE, String.valueOf(_durable)); - arguments.put(AUTH_MECHANISM, _authMechanism); - arguments.put(USERNAME, _username); - arguments.put(PASSWORD, _password); - - return Collections.unmodifiableMap(arguments); - } - - private final boolean updateState(State expected, State newState) - { - return _stateUpdater.compareAndSet(this,expected,newState); - } - - private void makeConnection() - { - _threadPool.execute(_makeConnectionTask); - } - - - - private void doMakeConnection() - { - if(updateState(State.DOWN, State.ESTABLISHING)) - { - try - { - _qpidConnection.setConnectionDelegate(new ClientDelegate(new ConnectionSettings()) - { - protected SaslClient createSaslClient(List<Object> brokerMechs) throws ConnectionException, - SaslException - { - Map<String,Object> saslProps = new HashMap<String,Object>(); - - - CallbackHandler cbh = new CallbackHandler() - { - public void handle(final Callback[] callbacks) - throws IOException, UnsupportedCallbackException - { - for (int i = 0; i < callbacks.length; i++) - { - Callback cb = callbacks[i]; - if (cb instanceof NameCallback) - { - ((NameCallback)cb).setName(_username); - } - else if (cb instanceof PasswordCallback) - { - ((PasswordCallback)cb).setPassword(_password.toCharArray()); - } - else - { - throw new UnsupportedCallbackException(cb); - } - } - - } - }; - final SaslClient sc = Sasl.createSaslClient(new String[] {"PLAIN"}, null, - getConnectionSettings().getSaslProtocol(), - getConnectionSettings().getSaslServerName(), - saslProps, cbh); - - return sc; - }}); - - _qpidConnection.connect(_host, _port, _remoteVhost, _username, _password, "ssl".equals(_transport), _authMechanism); - - final Map<String,Object> serverProps = _qpidConnection.getServerProperties(); - - _remoteFederationTag = (String) serverProps.get(ServerPropertyNames.FEDERATION_TAG); - if(_remoteFederationTag == null) - { - _remoteFederationTag = UUID.fromString(_transport+":"+_host+":"+_port).toString(); - } - _qpidConnection.setSessionFactory(new SessionFactory()); - - updateState(State.ESTABLISHING, State.OPERATIONAL); - - _retryDelay = 1; - - for(Bridge bridge : _bridges.values()) - { - if(_state != State.OPERATIONAL) - { - break; - } - addBridge(bridge); - } - - - } - catch (TransportException e) - { - _lastErrorMessage = e.getMessage(); - if(_retryDelay < 60) - { - _retryDelay <<= 1; - } - - updateState(State.ESTABLISHING, State.DOWN); - _activeBridges.clear(); - scheduleConnectionRetry(); - } - } - } - - private void scheduleConnectionRetry() - { - if(_state != State.DELETED) - { - _threadPool.schedule(_makeConnectionTask, _retryDelay, TimeUnit.SECONDS); - } - } - - public VirtualHost getVirtualHost() - { - return _virtualHost; - } - - public String getTransport() - { - return _transport; - } - - public String getHost() - { - return _host; - } - - public int getPort() - { - return _port; - } - - public String getRemoteVhost() - { - return _remoteVhost; - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public LinkConfigType getConfigType() - { - return LinkConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - - public boolean isDurable() - { - return _durable; - } - - public String getAuthMechanism() - { - return _authMechanism; - } - - public String getUsername() - { - return _username; - } - - public String getPassword() - { - return _password; - } - - @Override - public boolean equals(final Object o) - { - if (this == o) - { - return true; - } - if (o == null || getClass() != o.getClass()) - { - return false; - } - - final BrokerLink that = (BrokerLink) o; - - if (_port != that._port) - { - return false; - } - if (_host != null ? !_host.equals(that._host) : that._host != null) - { - return false; - } - if (_remoteVhost != null ? !_remoteVhost.equals(that._remoteVhost) : that._remoteVhost != null) - { - return false; - } - if (_transport != null ? !_transport.equals(that._transport) : that._transport != null) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int result = _transport != null ? _transport.hashCode() : 0; - result = 31 * result + (_host != null ? _host.hashCode() : 0); - result = 31 * result + _port; - result = 31 * result + (_remoteVhost != null ? _remoteVhost.hashCode() : 0); - return result; - } - - public void close() - { - if(_closing.compareAndSet(false,true)) - { - // TODO - close connection - for(Bridge bridge : _bridges.values()) - { - bridge.close(); - } - _bridges.clear(); - - _virtualHost.removeBrokerConnection(this); - } - } - - public long getCreateTime() - { - return _createTime; - } - - public void createBridge(final boolean durable, - final boolean dynamic, - final boolean srcIsQueue, - final boolean srcIsLocal, - final String src, - final String dest, - final String key, - final String tag, - final String excludes) - { - if(!_closing.get()) - { - Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), durable,dynamic,srcIsQueue,srcIsLocal,src,dest,key,tag,excludes); - if(_bridges.putIfAbsent(bridge, bridge) == null) - { - - addBridge(bridge); - } - } - - - } - - public void createBridge(final UUID id, final long createTime, final Map<String, String> arguments) - { - if(!_closing.get()) - { - Bridge bridge = new Bridge(this, _bridgeId.incrementAndGet(), id, createTime, arguments); - if(_bridges.putIfAbsent(bridge, bridge) == null) - { - - addBridge(bridge); - } - } - } - - - private void addBridge(final Bridge bridge) - { - getConfigStore().addConfiguredObject(bridge); - - if(_state == State.OPERATIONAL && (_activeBridges.putIfAbsent(bridge,bridge) == null)) - { - - - Session session = _qpidConnection.createSession("Bridge(" - + (bridge.isDurable() ? "durable" : "transient") - + "," + (bridge.isDynamic() ? "dynamic" : "static") - + "," + (bridge.isQueueBridge() ? "queue" : "exchange") - + "," + (bridge.isLocalSource() ? "local-src" : "remote-src") - + ",[Source: '" + bridge.getSource() + "']" - + ",[Destination: '" + bridge.getDestination() + "']" - + ",[Key: '" + bridge.getKey() + "']" - + ",[Tag: '" + bridge.getTag() + "']" - + ".[Excludes: '" + bridge.getExcludes() + "'])"); - bridge.setSession(session); - - - if(_closing.get()) - { - bridge.close(); - } - } - - } - - public void opened(final Connection connection) - { - // this method not called - } - - public void exception(final Connection connection, final ConnectionException exception) - { - _exception = exception; - _lastErrorMessage = exception.getMessage(); - - } - - public void closed(final Connection connection) - { - State currentState = _state; - if(currentState != State.DOWN && currentState != State.DELETED && updateState(currentState, State.DOWN)) - { - scheduleConnectionRetry(); - } - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - - public String getFederationTag() - { - return getVirtualHost().getFederationTag(); - } - - public String getRemoteFederationTag() - { - return _remoteFederationTag; - } - - public String getState() - { - return _state.name(); - } - - public String getLastError() - { - return _lastErrorMessage; - } - - @Override - public String toString() - { - return "BrokerLink{" + - " _id=" + _qmfId + - ", _transport='" + _transport + '\'' + - ", _host='" + _host + '\'' + - ", _port=" + _port + - ", _remoteVhost='" + _remoteVhost + '\'' + - ", _durable=" + _durable + - ", _authMechanism='" + _authMechanism + '\'' + - ", _username='" + _username + '\'' + - ", _password='" + _password + '\'' + - ", _virtualHost=" + _virtualHost + - ", _createTime=" + _createTime + - ", _remoteFederationTag='" + _remoteFederationTag + '\'' + - ", _state=" + _state + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java index b8c8411c5d..0339287e38 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java @@ -30,11 +30,11 @@ import org.apache.qpid.framing.ConnectionSecureOkBody; import org.apache.qpid.framing.ConnectionTuneBody; import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; @@ -59,9 +59,10 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener public void methodReceived(AMQStateManager stateManager, ConnectionSecureOkBody body, int channelId) throws AMQException { + Broker broker = stateManager.getBroker(); AMQProtocolSession session = stateManager.getProtocolSession(); - AuthenticationManager authMgr = stateManager.getAuthenticationManager(); + SubjectCreator subjectCreator = stateManager.getSubjectCreator(); SaslServer ss = session.getSaslServer(); if (ss == null) @@ -69,7 +70,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener throw new AMQException("No SASL context set up in session"); } MethodRegistry methodRegistry = session.getMethodRegistry(); - AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); + SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse()); switch (authResult.getStatus()) { case ERROR: @@ -97,9 +98,9 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); ConnectionTuneBody tuneBody = - methodRegistry.createConnectionTuneBody(ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(), - ConnectionStartOkMethodHandler.getConfiguredFrameSize(), - ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay()); + methodRegistry.createConnectionTuneBody((Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT), + BrokerProperties.DEFAULT_FRAME_SIZE, + (Integer)broker.getAttribute(Broker.HEART_BEAT_DELAY)); session.writeFrame(tuneBody.generateFrame(0)); session.setAuthorizedSubject(authResult.getSubject()); disposeSaslServer(session); diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java index a522b9f60f..e70fa6a37b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java @@ -29,12 +29,11 @@ import org.apache.qpid.framing.ConnectionStartOkBody; import org.apache.qpid.framing.ConnectionTuneBody; import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; @@ -60,16 +59,17 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< public void methodReceived(AMQStateManager stateManager, ConnectionStartOkBody body, int channelId) throws AMQException { + Broker broker = stateManager.getBroker(); AMQProtocolSession session = stateManager.getProtocolSession(); _logger.info("SASL Mechanism selected: " + body.getMechanism()); _logger.info("Locale selected: " + body.getLocale()); - AuthenticationManager authMgr = stateManager.getAuthenticationManager(); + SubjectCreator subjectCreator = stateManager.getSubjectCreator(); SaslServer ss = null; try { - ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal()); + ss = subjectCreator.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN(), session.getPeerPrincipal()); if (ss == null) { @@ -78,7 +78,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< session.setSaslServer(ss); - final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); + final SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, body.getResponse()); //save clientProperties session.setClientProperties(body.getClientProperties()); @@ -112,9 +112,9 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(), - getConfiguredFrameSize(), - ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay()); + ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody((Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT), + BrokerProperties.DEFAULT_FRAME_SIZE, + (Integer)broker.getAttribute(Broker.HEART_BEAT_DELAY)); session.writeFrame(tuneBody.generateFrame(0)); break; case CONTINUE: @@ -148,13 +148,6 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< } } - static int getConfiguredFrameSize() - { - final ServerConfiguration config = ApplicationRegistry.getInstance().getConfiguration(); - final int framesize = config.getFrameSize(); - _logger.info("Framesize set to " + framesize); - return framesize; - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java index 8756409f64..eed0cd6020 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java @@ -101,7 +101,7 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange exchange = exchangeFactory.createExchange(exchangeName == null ? null : exchangeName.intern(), body.getType() == null ? null : body.getType().intern(), body.getDurable(), - body.getPassive(), body.getTicket()); + body.getAutoDelete(), body.getTicket()); exchangeRegistry.registerExchange(exchange); if (exchange.isDurable()) diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index ae725b9ec1..194c3d6351 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -38,7 +38,6 @@ import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.store.DurableConfigurationStore; @@ -59,8 +58,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar return _instance; } - private boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); - public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException { final AMQProtocolSession protocolConnection = stateManager.getProtocolSession(); @@ -148,13 +145,11 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar }); } } - if (autoRegister) - { - Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); + Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); - virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange, Collections.EMPTY_MAP); - _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")"); - } + virtualHost.getBindingFactory().addBinding(String.valueOf(queueName), queue, defaultExchange, + Collections.<String, Object> emptyMap()); + _logger.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getNameShortString() + ")"); } } else if (queue.isExclusive() && !queue.isDurable() && (owningSession == null || owningSession.getConnectionModel() != protocolConnection)) diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java b/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java index 545f2adea2..98da9074ef 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/AbstractRootMessageLogger.java @@ -20,7 +20,6 @@ */ package org.apache.qpid.server.logging; -import org.apache.qpid.server.configuration.ServerConfiguration; public abstract class AbstractRootMessageLogger implements RootMessageLogger { @@ -33,9 +32,9 @@ public abstract class AbstractRootMessageLogger implements RootMessageLogger } - public AbstractRootMessageLogger(ServerConfiguration config) + public AbstractRootMessageLogger(boolean statusUpdatesEnabled) { - _enabled = config.getStatusUpdatesEnabled(); + _enabled = statusUpdatesEnabled; } public boolean isEnabled() diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java b/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java index ec506ab51c..b4e9f2f333 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/Log4jMessageLogger.java @@ -20,23 +20,18 @@ */ package org.apache.qpid.server.logging; -import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.ServerConfiguration; - public class Log4jMessageLogger extends AbstractRootMessageLogger { - public static final Level LEVEL = Level.toLevel("INFO"); - public Log4jMessageLogger() { super(); } - public Log4jMessageLogger(ServerConfiguration config) + public Log4jMessageLogger(boolean statusUpdatesEnabled) { - super(config); + super(statusUpdatesEnabled); } @Override @@ -51,7 +46,7 @@ public class Log4jMessageLogger extends AbstractRootMessageLogger if(isEnabled()) { Logger logger = Logger.getLogger(logHierarchy); - return logger.isEnabledFor(LEVEL); + return logger.isInfoEnabled(); } else { @@ -69,7 +64,6 @@ public class Log4jMessageLogger extends AbstractRootMessageLogger public void rawMessage(String message, Throwable throwable, String logHierarchy) { Logger logger = Logger.getLogger(logHierarchy); - - logger.log(LEVEL, message, throwable); + logger.info(message, throwable); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java b/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java index a1065319d3..d053dd3fe2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/LogRecorder.java @@ -90,7 +90,6 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record> public LogRecorder() { - Logger.getRootLogger().addAppender(this); } @@ -109,7 +108,11 @@ public class LogRecorder implements Appender, Iterable<LogRecorder.Record> @Override public void close() { - //TODO - Implement + } + + public void closeLogRecorder() + { + Logger.getRootLogger().removeAppender(this); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java new file mode 100644 index 0000000000..8cf121b3d9 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/AbstractManagementActor.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.logging.actors; + +import java.security.AccessController; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; + +public abstract class AbstractManagementActor extends AbstractActor +{ + /** + * Holds the principal name to display when principal subject is not available. + * <p> + * This is useful for cases when users invoke JMX operation over JConsole + * attached to the local JVM. + */ + protected static final String UNKNOWN_PRINCIPAL = "N/A"; + + /** used when the principal name cannot be discovered from the Subject */ + private final String _fallbackPrincipalName; + + public AbstractManagementActor(RootMessageLogger rootLogger, String fallbackPrincipalName) + { + super(rootLogger); + _fallbackPrincipalName = fallbackPrincipalName; + } + + /** + * Returns current {@link AuthenticatedPrincipal} name or {@link #_fallbackPrincipalName} + * if it can't be found. + */ + protected String getPrincipalName() + { + String identity = _fallbackPrincipalName; + + final Subject subject = Subject.getSubject(AccessController.getContext()); + if (subject != null) + { + AuthenticatedPrincipal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(subject); + if(authenticatedPrincipal != null) + { + identity = authenticatedPrincipal.getName(); + } + } + return identity; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java index 97134515a0..6251471139 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/CurrentActor.java @@ -105,6 +105,11 @@ public class CurrentActor { Stack<LogActor> stack = _currentActor.get(); stack.pop(); + + if (stack.isEmpty()) + { + _currentActor.remove(); + } } /** diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java new file mode 100644 index 0000000000..9b445c2bd9 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/HttpManagementActor.java @@ -0,0 +1,62 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.logging.actors; + +import java.text.MessageFormat; + +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.subjects.LogSubjectFormat; + +/** + * HttpManagement actor to use in {@link AbstractServlet} to log all http management operational logging. + * + * An instance is required per http Session. + */ +public class HttpManagementActor extends AbstractManagementActor +{ + private String _cachedLogString; + private String _lastPrincipalName; + private String _address; + + public HttpManagementActor(RootMessageLogger rootLogger, String ip, int port) + { + super(rootLogger, UNKNOWN_PRINCIPAL); + _address = ip + ":" + port; + } + + private synchronized String getAndCacheLogString() + { + String principalName = getPrincipalName(); + + if(!principalName.equals(_lastPrincipalName)) + { + _lastPrincipalName = principalName; + _cachedLogString = "[" + MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, _address) + "] "; + } + + return _cachedLogString; + } + + public String getLogMessage() + { + return getAndCacheLogString(); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java index a2f3506502..ba5ea47fc1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/actors/ManagementActor.java @@ -21,58 +21,31 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.subjects.LogSubjectFormat; -import javax.management.remote.JMXPrincipal; -import javax.security.auth.Subject; -import java.security.AccessController; -import java.security.Principal; import java.text.MessageFormat; -import java.util.Set; /** * Management actor to use in {@link MBeanInvocationHandlerImpl} to log all management operational logging. */ -public class ManagementActor extends AbstractActor +public class ManagementActor extends AbstractManagementActor { - /** - * Holds the principal name to display when principal subject is not available. - * <p> - * This is useful for cases when users invoke JMX operation over JConsole - * attached to the local JVM. - */ - private static final String UNKNOWN_PRINCIPAL = "N/A"; - private String _lastThreadName = null; /** - * LOG FORMAT for the ManagementActor, - * Uses a MessageFormat call to insert the required values according to - * these indices: - * - * 0 - User ID - * 1 - IP - */ - public static final String MANAGEMENT_FORMAT = "mng:{0}({1})"; - - /** * The logString to be used for logging */ private String _logStringContainingPrincipal; - /** used when the principal name cannot be discovered from the Subject */ - private final String _fallbackPrincipalName; - /** @param rootLogger The RootLogger to use for this Actor */ public ManagementActor(RootMessageLogger rootLogger) { - super(rootLogger); - _fallbackPrincipalName = UNKNOWN_PRINCIPAL; + super(rootLogger, UNKNOWN_PRINCIPAL); } public ManagementActor(RootMessageLogger rootLogger, String principalName) { - super(rootLogger); - _fallbackPrincipalName = principalName; + super(rootLogger, principalName); } private synchronized String getAndCacheLogString() @@ -96,7 +69,7 @@ public class ManagementActor extends AbstractActor if (split.length == 2) { String ip = currentName.split("-")[1]; - actor = MessageFormat.format(MANAGEMENT_FORMAT, principalName, ip); + actor = MessageFormat.format(LogSubjectFormat.MANAGEMENT_FORMAT, principalName, ip); } else { @@ -119,33 +92,8 @@ public class ManagementActor extends AbstractActor return logString; } - /** - * Returns current JMX principal name. - * - * @return principal name or null if principal can not be found - */ - private String getPrincipalName() - { - String identity = _fallbackPrincipalName; - - // retrieve Subject from current AccessControlContext - final Subject subject = Subject.getSubject(AccessController.getContext()); - if (subject != null) - { - // retrieve JMXPrincipal from Subject - final Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class); - if (principals != null && !principals.isEmpty()) - { - final Principal principal = principals.iterator().next(); - identity = principal.getName(); - } - } - return identity; - } - public String getLogMessage() { return getAndCacheLogString(); } - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacade.java index 931171b175..6a961c8fa4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingFacade.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/log4j/LoggingManagementFacade.java @@ -58,49 +58,49 @@ import java.util.Random; * turn {@link Logger} on, off and control their {@link Level}, and the manipulation and reload * of the log4j configuration file. */ -public class LoggingFacade +public class LoggingManagementFacade { private static Logger LOGGER; - private static transient LoggingFacade _instance; + private static transient LoggingManagementFacade _instance; private final String _filename; private final int _delay; - public static LoggingFacade configure(String filename) throws LoggingFacadeException + public static LoggingManagementFacade configure(String filename) throws LoggingFacadeException { - _instance = new LoggingFacade(filename); + _instance = new LoggingManagementFacade(filename); return _instance; } - public static LoggingFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException + public static LoggingManagementFacade configureAndWatch(String filename, int delay) throws LoggingFacadeException { - _instance = new LoggingFacade(filename, delay); + _instance = new LoggingManagementFacade(filename, delay); return _instance; } - public static LoggingFacade getCurrentInstance() + public static LoggingManagementFacade getCurrentInstance() { return _instance; } - private LoggingFacade(String filename) + private LoggingManagementFacade(String filename) { DOMConfigurator.configure(filename); if(LOGGER == null) { - LOGGER = Logger.getLogger(LoggingFacade.class); + LOGGER = Logger.getLogger(LoggingManagementFacade.class); } _filename = filename; _delay = 0; } - private LoggingFacade(String filename, int delay) + private LoggingManagementFacade(String filename, int delay) { DOMConfigurator.configureAndWatch(filename, delay); if(LOGGER == null) { - LOGGER = Logger.getLogger(LoggingFacade.class); + LOGGER = Logger.getLogger(LoggingManagementFacade.class); } _filename = filename; diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties index ac77f674f2..7924be28d3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/messages/ManagementConsole_logmessages.properties @@ -18,16 +18,21 @@ # # Default File used for all non-defined locales. # -STARTUP = MNG-1001 : Startup +# 0 - Management Type +STARTUP = MNG-1001 : {0} Management Startup # 0 - Service # 1 - Port LISTENING = MNG-1002 : Starting : {0} : Listening on port {1,number,#} # 0 - Service # 1 - Port SHUTTING_DOWN = MNG-1003 : Shutting down : {0} : port {1,number,#} -READY = MNG-1004 : Ready[ : Using the platform JMX Agent] -STOPPED = MNG-1005 : Stopped +# 0 - Management Type +READY = MNG-1004 : {0} Management Ready +# 0 - Management Type +STOPPED = MNG-1005 : {0} Management Stopped # 0 - Path SSL_KEYSTORE = MNG-1006 : Using SSL Keystore : {0} +# 0 - Username OPEN = MNG-1007 : Open : User {0} +# 0 - Username CLOSE = MNG-1008 : Close : User {0}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java index 859d7e2a27..bcb9cb2ac4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java @@ -76,7 +76,7 @@ public class ChannelLogSubject extends AbstractLogSubject setLogStringWithFormat(CHANNEL_FORMAT, connection == null ? -1L : connection.getConnectionId(), session.getAuthorizedPrincipal() == null ? "?" : session.getAuthorizedPrincipal().getName(), - (connection == null || connection.getConfig() == null) ? "?" : connection.getConfig().getAddress(), + (connection == null || connection.getRemoteAddressString() == null) ? "?" : connection.getRemoteAddressString(), session.getVirtualHost().getName(), session.getChannel()); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java index 28c4f0d52a..7611ee1a88 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java +++ b/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/LogSubjectFormat.java @@ -32,11 +32,19 @@ package org.apache.qpid.server.logging.subjects; public class LogSubjectFormat { + private LogSubjectFormat() { } /** + * LOG FORMAT for the ManagementActors, + * 0 - User ID + * 1 - IP[:Port] + */ + public static final String MANAGEMENT_FORMAT = "mng:{0}({1})"; + + /** * LOG FORMAT for the Subscription Log Subject * 0 - Subscription ID */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java index 2cc1a92853..e01f20d54f 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java @@ -342,6 +342,14 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData { private final AMQPDescribedTypeRegistry _typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + private MetaDataFactory() + { + _typeRegistry.registerTransportLayer(); + _typeRegistry.registerMessagingLayer(); + _typeRegistry.registerTransactionLayer(); + _typeRegistry.registerSecurityLayer(); + } + public MessageMetaData_1_0 createMetaData(ByteBuffer buf) { ValueHandler valueHandler = new ValueHandler(_typeRegistry); @@ -354,7 +362,8 @@ public class MessageMetaData_1_0 implements StorableMessageMetaData try { ByteBuffer encodedBuf = buf.duplicate(); - sections.add((Section) valueHandler.parse(buf)); + Object parse = valueHandler.parse(buf); + sections.add((Section) parse); encodedBuf.limit(buf.position()); encodedSections.add(encodedBuf); diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java index 6000886956..417f6036ab 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java @@ -24,6 +24,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; + public interface AuthenticationProvider extends ConfiguredObject { @@ -52,4 +55,15 @@ public interface AuthenticationProvider extends ConfiguredObject TYPE)); //children Collection<VirtualHostAlias> getVirtualHostPortBindings(); + + String getName(); + + /** + * A temporary method to create SubjectCreator. + * + * TODO: move all the functionality from SubjectCreator into AuthenticationProvider + */ + SubjectCreator getSubjectCreator(); + + void setGroupAccessor(GroupPrincipalAccessor groupPrincipalAccessor); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java index 08b01a1b65..fbecf1965b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java @@ -20,12 +20,20 @@ */ package org.apache.qpid.server.model; +import java.net.SocketAddress; import java.security.AccessControlException; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Map; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; + public interface Broker extends ConfiguredObject { @@ -44,9 +52,49 @@ public interface Broker extends ConfiguredObject String STATE = "state"; String TIME_TO_LIVE = "timeToLive"; String UPDATED = "updated"; + String DEFAULT_AUTHENTICATION_PROVIDER = "defaultAuthenticationProvider"; + String DEFAULT_VIRTUAL_HOST = "defaultVirtualHost"; + + String ALERT_THRESHOLD_MESSAGE_AGE = "alertThresholdMessageAge"; + String ALERT_THRESHOLD_MESSAGE_COUNT = "alertThresholdMessageCount"; + String ALERT_THRESHOLD_QUEUE_DEPTH = "alertThresholdQueueDepth"; + String ALERT_THRESHOLD_MESSAGE_SIZE = "alertThresholdMessageSize"; + String ALERT_REPEAT_GAP = "alertRepeatGap"; + String FLOW_CONTROL_SIZE_BYTES = "queueFlowControlSizeBytes"; + String FLOW_CONTROL_RESUME_SIZE_BYTES = "queueFlowResumeSizeBytes"; + String MAXIMUM_DELIVERY_ATTEMPTS = "maximumDeliveryAttempts"; + String DEAD_LETTER_QUEUE_ENABLED = "deadLetterQueueEnabled"; + String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod"; + + String SESSION_COUNT_LIMIT = "sessionCountLimit"; + String HEART_BEAT_DELAY = "heartBeatDelay"; + String STATISTICS_REPORTING_PERIOD = "statisticsReportingPeriod"; + String STATISTICS_REPORTING_RESET_ENABLED = "statisticsReportingResetEnabled"; + + /* + * A temporary attribute to pass the path to ACL file. + * TODO: It should be a part of AuthorizationProvider. + */ + String ACL_FILE = "aclFile"; + + /* + * A temporary attributes to set the broker default key/trust stores. + * TODO: Remove them after adding a full support to configure KeyStore/TrustStore via management layers. + */ + String KEY_STORE_PATH = "keyStorePath"; + String KEY_STORE_PASSWORD = "keyStorePassword"; + String KEY_STORE_CERT_ALIAS = "keyStoreCertAlias"; + String TRUST_STORE_PATH = "trustStorePath"; + String TRUST_STORE_PASSWORD = "trustStorePassword"; + + /* + * A temporary attributes to set the broker group file. + * TODO: Remove them after adding a full support to configure authorization providers via management layers. + */ + String GROUP_FILE = "groupFile"; // Attributes - public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableList( Arrays.asList(BUILD_VERSION, BYTES_RETAINED, @@ -62,7 +110,32 @@ public interface Broker extends ConfiguredObject NAME, STATE, TIME_TO_LIVE, - UPDATED)); + UPDATED, + DEFAULT_AUTHENTICATION_PROVIDER, + DEFAULT_VIRTUAL_HOST, + ALERT_THRESHOLD_MESSAGE_AGE, + ALERT_THRESHOLD_MESSAGE_COUNT, + ALERT_THRESHOLD_QUEUE_DEPTH, + ALERT_THRESHOLD_MESSAGE_SIZE, + ALERT_REPEAT_GAP, + FLOW_CONTROL_SIZE_BYTES, + FLOW_CONTROL_RESUME_SIZE_BYTES, + MAXIMUM_DELIVERY_ATTEMPTS, + DEAD_LETTER_QUEUE_ENABLED, + HOUSEKEEPING_CHECK_PERIOD, + SESSION_COUNT_LIMIT, + HEART_BEAT_DELAY, + STATISTICS_REPORTING_PERIOD, + STATISTICS_REPORTING_RESET_ENABLED, + + ACL_FILE, + KEY_STORE_PATH, + KEY_STORE_PASSWORD, + KEY_STORE_CERT_ALIAS, + TRUST_STORE_PATH, + TRUST_STORE_PASSWORD, + GROUP_FILE + )); //children Collection < VirtualHost > getVirtualHosts(); @@ -75,6 +148,49 @@ public interface Broker extends ConfiguredObject LifetimePolicy lifetime, long ttl, Map<String, Object> attributes) throws AccessControlException, IllegalArgumentException; - void deleteVirtualHost(VirtualHost virtualHost) - throws AccessControlException, IllegalStateException; + AuthenticationProvider getDefaultAuthenticationProvider(); + + Collection<GroupProvider> getGroupProviders(); + + /** + * A temporary hack to expose root message logger via broker instance. + * TODO We need a better way to do operational logging, for example, via logging listeners + */ + RootMessageLogger getRootMessageLogger(); + + /** + * A temporary hack to expose security manager via broker instance. + * TODO We need to add and implement an authorization provider configured object instead + */ + SecurityManager getSecurityManager(); + + /** + * TODO: A temporary hack to expose log recorder via broker instance. + */ + LogRecorder getLogRecorder(); + + VirtualHost findVirtualHostByName(String name); + + /** + * Get the SubjectCreator for the given socket address. + * TODO: move the authentication related functionality into host aliases and AuthenticationProviders + * + * @param address The (listening) socket address for which the AuthenticationManager is required + */ + SubjectCreator getSubjectCreator(SocketAddress localAddress); + + Collection<KeyStore> getKeyStores(); + + Collection<TrustStore> getTrustStores(); + + /* + * TODO: Remove this method. Eventually the broker will become a registry. + */ + VirtualHostRegistry getVirtualHostRegistry(); + + KeyStore getDefaultKeyStore(); + + TrustStore getDefaultTrustStore(); + + TaskExecutor getTaskExecutor(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java index 78b98faffe..bd7da962ba 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java @@ -36,4 +36,5 @@ public interface ConfigurationChangeListener void childRemoved(ConfiguredObject object, ConfiguredObject child); + void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java index 414b2d083a..d567a3aa44 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java @@ -25,6 +25,9 @@ import java.util.Collection; import java.util.Map; import java.util.UUID; +/** + * An object that can be "managed" (eg via the web interface) and usually read from configuration. + */ public interface ConfiguredObject { @@ -47,7 +50,7 @@ public interface ConfiguredObject * Attempt to change the name of the object * * Request a change to the name of the object. The caller must pass in the name it believes the object currently - * has. If the current name differes from this expected value, then no name change will occur + * has. If the current name differs from this expected value, then no name change will occur * * @param currentName the name the caller believes the object to have * @param desiredName the name the caller would like the object to have @@ -198,14 +201,25 @@ public interface ConfiguredObject /** - * Return the value for the given attribute + * Return the value for the given attribute name. The actual attribute value + * is returned if the configured object has such attribute set. If not, the + * value is looked default attributes. * - * @param name the name of the attribute - * @return the value of the attribute at the object (or null if the attribute is not set + * @param name + * the name of the attribute + * @return the value of the attribute at the object (or null if the + * attribute value is set neither on object itself no in defaults) */ Object getAttribute(String name); /** + * Return the map containing only explicitly set attributes + * + * @return the map with the attributes + */ + Map<String, Object> getActualAttributes(); + + /** * Set the value of an attribute * * @param name the name of the attribute to be set diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Group.java b/java/broker/src/main/java/org/apache/qpid/server/model/Group.java new file mode 100644 index 0000000000..aacd515107 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Group.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface Group extends ConfiguredObject +{ + String CREATED = "created"; + String DURABLE = "durable"; + String ID = "id"; + String LIFETIME_POLICY = "lifetimePolicy"; + String NAME = "name"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String UPDATED = "updated"; + + // Attributes + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED + )); + + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java b/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java new file mode 100644 index 0000000000..6832cc6fa6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/GroupMember.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface GroupMember extends ConfiguredObject +{ + String CREATED = "created"; + String DURABLE = "durable"; + String ID = "id"; + String LIFETIME_POLICY = "lifetimePolicy"; + String NAME = "name"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String UPDATED = "updated"; + + // Attributes + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED + )); + + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java b/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java new file mode 100644 index 0000000000..9016f97927 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/GroupProvider.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +public interface GroupProvider extends ConfiguredObject +{ + public static final String ID = "id"; + public static final String DESCRIPTION = "description"; + public static final String NAME = "name"; + public static final String STATE = "state"; + public static final String DURABLE = "durable"; + public static final String LIFETIME_POLICY = "lifetimePolicy"; + public static final String TIME_TO_LIVE = "timeToLive"; + public static final String CREATED = "created"; + public static final String UPDATED = "updated"; + public static final String TYPE = "type"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList(ID, + NAME, + DESCRIPTION, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + TYPE)); + + Set<Principal> getGroupPrincipalsForUser(String username); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java b/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java new file mode 100644 index 0000000000..959714656b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface KeyStore extends TrustStore +{ + + String CERTIFICATE_ALIAS = "certificateAlias"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + DESCRIPTION, + PATH, + PASSWORD, + TYPE, + KEY_MANAGER_FACTORY_ALGORITHM, + CERTIFICATE_ALIAS + )); + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/java/broker/src/main/java/org/apache/qpid/server/model/Model.java index 36179fc105..2c05dce9cb 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Model.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Model.java @@ -47,6 +47,10 @@ public class Model addRelationship(Broker.class, VirtualHost.class); addRelationship(Broker.class, Port.class); addRelationship(Broker.class, AuthenticationProvider.class); + addRelationship(Broker.class, GroupProvider.class); + addRelationship(Broker.class, TrustStore.class); + addRelationship(Broker.class, KeyStore.class); + addRelationship(Broker.class, Plugin.class); addRelationship(VirtualHost.class, Exchange.class); addRelationship(VirtualHost.class, Queue.class); @@ -54,6 +58,10 @@ public class Model addRelationship(VirtualHost.class, VirtualHostAlias.class); addRelationship(AuthenticationProvider.class, User.class); + addRelationship(User.class, GroupMember.class); + + addRelationship(GroupProvider.class, Group.class); + addRelationship(Group.class, GroupMember.class); addRelationship(Connection.class, Session.class); diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java b/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java new file mode 100644 index 0000000000..b9503a5841 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Plugin.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface Plugin extends ConfiguredObject +{ + //Hack, using it for the class name only for consistency with the other things. + String CREATED = "created"; + String DURABLE = "durable"; + String ID = "id"; + String LIFETIME_POLICY = "lifetimePolicy"; + String NAME = "name"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String UPDATED = "updated"; + + // Attributes + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED + )); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Port.java b/java/broker/src/main/java/org/apache/qpid/server/model/Port.java index 50c0ebcd14..2f94c3cab7 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Port.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Port.java @@ -39,6 +39,16 @@ public interface Port extends ConfiguredObject String PORT = "port"; String PROTOCOLS = "protocols"; String TRANSPORTS = "transports"; + String TCP_NO_DELAY = "tcpNoDelay"; + String SEND_BUFFER_SIZE = "sendBufferSize"; + String RECEIVE_BUFFER_SIZE = "receiveBufferSize"; + String NEED_CLIENT_AUTH = "needClientAuth"; + String WANT_CLIENT_AUTH = "wantClientAuth"; + + /** + * TODO: rename it to AUTHENTICATION_MANAGER_ID or introduce relationships + */ + String AUTHENTICATION_MANAGER = "authenticationManager"; // Attributes public static final Collection<String> AVAILABLE_ATTRIBUTES = @@ -55,7 +65,13 @@ public interface Port extends ConfiguredObject BINDING_ADDRESS, PORT, PROTOCOLS, - TRANSPORTS + TRANSPORTS, + TCP_NO_DELAY, + SEND_BUFFER_SIZE, + RECEIVE_BUFFER_SIZE, + NEED_CLIENT_AUTH, + WANT_CLIENT_AUTH, + AUTHENTICATION_MANAGER )); @@ -88,4 +104,8 @@ public interface Port extends ConfiguredObject //children Collection<VirtualHostAlias> getVirtualHostBindings(); Collection<Connection> getConnections(); + + AuthenticationProvider getAuthenticationProvider(); + + void setAuthenticationProvider(AuthenticationProvider authenticationProvider); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java b/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java index 5d9de69f9a..6cd5eb23a4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Protocol.java @@ -20,14 +20,95 @@ */ package org.apache.qpid.server.model; +import java.util.Collection; +import java.util.EnumSet; + +import org.apache.qpid.server.protocol.AmqpProtocolVersion; + public enum Protocol { - AMQP_0_8, - AMQP_0_9, - AMQP_0_9_1, - AMQP_0_10, - AMQP_1_0, - JMX, - HTTP, - HTTPS + AMQP_0_8(ProtocolType.AMQP), + AMQP_0_9(ProtocolType.AMQP), + AMQP_0_9_1(ProtocolType.AMQP), + AMQP_0_10(ProtocolType.AMQP), + AMQP_1_0(ProtocolType.AMQP), + JMX_RMI(ProtocolType.JMX), + HTTP(ProtocolType.HTTP), + HTTPS(ProtocolType.HTTP), + RMI(ProtocolType.RMI); + + private final ProtocolType _protocolType; + + private Protocol(ProtocolType type) + { + _protocolType = type; + } + + public ProtocolType getProtocolType() + { + return _protocolType; + } + + public boolean isAMQP() + { + return _protocolType == ProtocolType.AMQP; + } + + public AmqpProtocolVersion toAmqpProtocolVersion() + { + switch(this) + { + case AMQP_0_8: + return AmqpProtocolVersion.v0_8; + case AMQP_0_9: + return AmqpProtocolVersion.v0_9; + case AMQP_0_9_1: + return AmqpProtocolVersion.v0_9_1; + case AMQP_0_10: + return AmqpProtocolVersion.v0_10; + case AMQP_1_0: + return AmqpProtocolVersion.v1_0_0; + default: + throw new IllegalArgumentException(this + " is not an known AMQP protocol"); + } + } + + public static Protocol valueOfObject(Object protocolObject) + { + Protocol protocol; + if (protocolObject instanceof Protocol) + { + protocol = (Protocol) protocolObject; + } + else + { + try + { + protocol = Protocol.valueOf(String.valueOf(protocolObject)); + } + catch (Exception e) + { + throw new IllegalArgumentException("Can't convert '" + protocolObject + + "' to one of the supported protocols: " + EnumSet.allOf(Protocol.class), e); + } + } + return protocol; + } + + public static boolean hasAmqpProtocol(Collection<Protocol> protocols) + { + for (Protocol protocol : protocols) + { + if (protocol.isAMQP()) + { + return true; + } + } + return false; + } + + public static enum ProtocolType + { + AMQP, HTTP, JMX, RMI; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java b/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java index 03cd46be01..ae6e5ac43a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/Transport.java @@ -20,8 +20,32 @@ */ package org.apache.qpid.server.model; +import java.util.EnumSet; + public enum Transport { TCP, - SSL + SSL; + + public static Transport valueOfObject(Object transportObject) + { + Transport transport; + if (transportObject instanceof Transport) + { + transport = (Transport) transportObject; + } + else + { + try + { + transport = Transport.valueOf(String.valueOf(transportObject)); + } + catch (Exception e) + { + throw new IllegalArgumentException("Can't convert '" + transportObject + + "' to one of the supported transports: " + EnumSet.allOf(Transport.class), e); + } + } + return transport; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java b/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java new file mode 100644 index 0000000000..0c322ae02f --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java @@ -0,0 +1,65 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public interface TrustStore extends ConfiguredObject +{ + String ID = "id"; + String NAME = "name"; + String DURABLE = "durable"; + String LIFETIME_POLICY = "lifetimePolicy"; + String STATE = "state"; + String TIME_TO_LIVE = "timeToLive"; + String CREATED = "created"; + String UPDATED = "updated"; + String DESCRIPTION = "description"; + + String PATH = "path"; + String PASSWORD = "password"; + String TYPE = "type"; + String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm"; + + public static final Collection<String> AVAILABLE_ATTRIBUTES = + Collections.unmodifiableList( + Arrays.asList( + ID, + NAME, + STATE, + DURABLE, + LIFETIME_POLICY, + TIME_TO_LIVE, + CREATED, + UPDATED, + DESCRIPTION, + PATH, + PASSWORD, + TYPE, + KEY_MANAGER_FACTORY_ALGORITHM + )); + + public String getPassword(); + + public void setPassword(String password); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java b/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java index 36b6a454dc..bcedd91596 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java @@ -63,6 +63,11 @@ public class UUIDGenerator return createUUID(User.class.getName(), authenticationProviderName, userName); } + public static UUID generateGroupUUID(String groupProviderName, String groupName) + { + return createUUID(Group.class.getName(), groupProviderName, groupName); + } + public static UUID generateVhostUUID(String virtualHostName) { return createUUID(VirtualHost.class.getName(), virtualHostName); @@ -77,4 +82,14 @@ public class UUIDGenerator { return createUUID(Consumer.class.getName(), virtualHostName, queueName, connectionRemoteAddress, channelNumber, consumerName); } + + public static UUID generateGroupMemberUUID(String groupProviderName, String groupName, String groupMemberName) + { + return createUUID(GroupMember.class.getName(), groupProviderName, groupName, groupMemberName); + } + + public static UUID generateBrokerChildUUID(String type, String childName) + { + return createUUID(type, childName); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/User.java b/java/broker/src/main/java/org/apache/qpid/server/model/User.java index d97bf46d31..675dc8f0d3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/User.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/User.java @@ -52,8 +52,6 @@ public interface User extends ConfiguredObject PASSWORD )); - public String getPassword(); - public void setPassword(String password); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java index 24a3d43386..5f4ec1d3a8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/VirtualHost.java @@ -21,6 +21,9 @@ package org.apache.qpid.server.model; import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.store.MessageStore; + import java.security.AccessControlException; import java.util.Arrays; import java.util.Collection; @@ -60,17 +63,16 @@ public interface VirtualHost extends ConfiguredObject String ALERT_THRESHOLD_QUEUE_DEPTH_BYTES = "alertThresholdQueueDepthBytes"; String ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES = "alertThresholdQueueDepthMessages"; String DEAD_LETTER_QUEUE_ENABLED = "deadLetterQueueEnabled"; - String FEDERATION_TAG = "federationTag"; String HOUSEKEEPING_CHECK_PERIOD = "housekeepingCheckPeriod"; String MAXIMUM_DELIVERY_ATTEMPTS = "maximumDeliveryAttempts"; String QUEUE_FLOW_CONTROL_SIZE_BYTES = "queueFlowControlSizeBytes"; String QUEUE_FLOW_RESUME_SIZE_BYTES = "queueFlowResumeSizeBytes"; - String STORE_CONFIGURATION = "storeConfiguration"; String STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE = "storeTransactionIdleTimeoutClose"; String STORE_TRANSACTION_IDLE_TIMEOUT_WARN = "storeTransactionIdleTimeoutWarn"; String STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = "storeTransactionOpenTimeoutClose"; String STORE_TRANSACTION_OPEN_TIMEOUT_WARN = "storeTransactionOpenTimeoutWarn"; String STORE_TYPE = "storeType"; + String STORE_PATH = "storePath"; String SUPPORTED_EXCHANGE_TYPES = "supportedExchangeTypes"; String SUPPORTED_QUEUE_TYPES = "supportedQueueTypes"; String CREATED = "created"; @@ -81,6 +83,8 @@ public interface VirtualHost extends ConfiguredObject String STATE = "state"; String TIME_TO_LIVE = "timeToLive"; String UPDATED = "updated"; + String CONFIG_PATH = "configPath"; + // Attributes public static final Collection<String> AVAILABLE_ATTRIBUTES = Collections.unmodifiableList( @@ -96,13 +100,12 @@ public interface VirtualHost extends ConfiguredObject SUPPORTED_EXCHANGE_TYPES, SUPPORTED_QUEUE_TYPES, DEAD_LETTER_QUEUE_ENABLED, - FEDERATION_TAG, HOUSEKEEPING_CHECK_PERIOD, MAXIMUM_DELIVERY_ATTEMPTS, QUEUE_FLOW_CONTROL_SIZE_BYTES, QUEUE_FLOW_RESUME_SIZE_BYTES, STORE_TYPE, - STORE_CONFIGURATION, + STORE_PATH, STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE, STORE_TRANSACTION_IDLE_TIMEOUT_WARN, STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE, @@ -111,7 +114,8 @@ public interface VirtualHost extends ConfiguredObject ALERT_THRESHOLD_MESSAGE_AGE, ALERT_THRESHOLD_MESSAGE_SIZE, ALERT_THRESHOLD_QUEUE_DEPTH_BYTES, - ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES)); + ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, + CONFIG_PATH)); @@ -149,4 +153,12 @@ public interface VirtualHost extends ConfiguredObject } void executeTransaction(TransactionalOperation op); + + /** + * A temporary hack to expose host security manager. + * TODO We need to add and implement an authorization provider configured object instead + */ + SecurityManager getSecurityManager(); + + MessageStore getMessageStore(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java index 7d6aa9b2cb..73e1f1e970 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java @@ -24,12 +24,18 @@ import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; + import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.IllegalStateTransitionException; import org.apache.qpid.server.model.State; +import org.apache.qpid.server.configuration.updater.ChangeStateTask; +import org.apache.qpid.server.configuration.updater.CreateChildTask; +import org.apache.qpid.server.configuration.updater.SetAttributeTask; +import org.apache.qpid.server.configuration.updater.TaskExecutor; abstract class AbstractAdapter implements ConfiguredObject { @@ -40,134 +46,78 @@ abstract class AbstractAdapter implements ConfiguredObject new ArrayList<ConfigurationChangeListener>(); private final UUID _id; + private final Map<String, Object> _defaultAttributes = new HashMap<String, Object>(); + private final TaskExecutor _taskExecutor; - protected AbstractAdapter(UUID id) + protected AbstractAdapter(UUID id, Map<String, Object> defaults, Map<String, Object> attributes, TaskExecutor taskExecutor) { + _taskExecutor = taskExecutor; _id = id; - } - - static String getStringAttribute(String name, Map<String,Object> attributes, String defaultVal) - { - final Object value = attributes.get(name); - return value == null ? defaultVal : String.valueOf(value); - } - - static Map getMapAttribute(String name, Map<String,Object> attributes, Map defaultVal) - { - final Object value = attributes.get(name); - if(value == null) - { - return defaultVal; - } - else if(value instanceof Map) + if (attributes != null) { - return (Map) value; + Collection<String> names = getAttributeNames(); + for (String name : names) + { + if (attributes.containsKey(name)) + { + _attributes.put(name, attributes.get(name)); + } + } } - else + if (defaults != null) { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map"); + _defaultAttributes.putAll(defaults); } } - - static <E extends Enum> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes, E defaultVal) + protected AbstractAdapter(UUID id, TaskExecutor taskExecutor) { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultVal; - } - else if(clazz.isInstance(obj)) - { - return (E) obj; - } - else if(obj instanceof String) - { - return (E) Enum.valueOf(clazz, (String)obj); - } - else - { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + clazz.getSimpleName()); - } + this(id, null, null, taskExecutor); } - static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue) + public final UUID getId() { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultValue; - } - else if(obj instanceof Boolean) - { - return (Boolean) obj; - } - else if(obj instanceof String) - { - return Boolean.parseBoolean((String) obj); - } - else - { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Boolean"); - } + return _id; } - static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue) + public State getDesiredState() { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultValue; - } - else if(obj instanceof Number) - { - return ((Number) obj).intValue(); - } - else if(obj instanceof String) - { - return Integer.valueOf((String) obj); - } - else - { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Integer"); - } + return null; //TODO } - static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue) + @Override + public final State setDesiredState(final State currentState, final State desiredState) + throws IllegalStateTransitionException, AccessControlException { - Object obj = attributes.get(name); - if(obj == null) - { - return defaultValue; - } - else if(obj instanceof Number) + if (_taskExecutor.isTaskExecutorThread()) { - return ((Number) obj).longValue(); - } - else if(obj instanceof String) - { - return Long.valueOf((String) obj); + if (setState(currentState, desiredState)) + { + notifyStateChanged(currentState, desiredState); + } } else { - throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Long"); + _taskExecutor.submitAndWait(new ChangeStateTask(this, currentState, desiredState)); } + return getActualState(); } - public final UUID getId() - { - return _id; - } + /** + * @return true when the state has been successfully updated to desiredState or false otherwise + */ + protected abstract boolean setState(State currentState, State desiredState); - public State getDesiredState() + protected void notifyStateChanged(final State currentState, final State desiredState) { - return null; //TODO - } - - public State setDesiredState(final State currentState, final State desiredState) - throws IllegalStateTransitionException, AccessControlException - { - return null; //TODO + synchronized (_changeListeners) + { + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) + { + listener.stateChanged(this, currentState, desiredState); + } + } } public void addChangeListener(final ConfigurationChangeListener listener) @@ -176,7 +126,7 @@ abstract class AbstractAdapter implements ConfiguredObject { throw new NullPointerException("Cannot add a null listener"); } - synchronized (this) + synchronized (_changeListeners) { if(!_changeListeners.contains(listener)) { @@ -191,39 +141,76 @@ abstract class AbstractAdapter implements ConfiguredObject { throw new NullPointerException("Cannot remove a null listener"); } - synchronized (this) + synchronized (_changeListeners) { return _changeListeners.remove(listener); } } - protected void childAdded(ConfiguredObject child) { - synchronized (this) + synchronized (_changeListeners) { - for(ConfigurationChangeListener listener : _changeListeners) + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) { listener.childAdded(this, child); } } } - protected void childRemoved(ConfiguredObject child) { - synchronized (this) + synchronized (_changeListeners) { - for(ConfigurationChangeListener listener : _changeListeners) + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) { listener.childRemoved(this, child); } } } - public Object getAttribute(final String name) + protected void attributeSet(String attrinuteName, Object oldAttributeValue, Object newAttributeValue) { - synchronized (this) + synchronized (_changeListeners) + { + List<ConfigurationChangeListener> copy = new ArrayList<ConfigurationChangeListener>(_changeListeners); + for(ConfigurationChangeListener listener : copy) + { + listener.attributeSet(this, attrinuteName, oldAttributeValue, newAttributeValue); + } + } + } + + private final Object getDefaultAttribute(String name) + { + return _defaultAttributes.get(name); + } + + @Override + public Object getAttribute(String name) + { + Object value = getActualAttribute(name); + if (value == null) + { + value = getDefaultAttribute(name); + } + return value; + } + + @Override + public final Map<String, Object> getActualAttributes() + { + synchronized (_attributes) + { + return new HashMap<String, Object>(_attributes); + } + } + + private Object getActualAttribute(final String name) + { + synchronized (_attributes) { return _attributes.get(name); } @@ -232,25 +219,41 @@ abstract class AbstractAdapter implements ConfiguredObject public Object setAttribute(final String name, final Object expected, final Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { - synchronized (this) + if (_taskExecutor.isTaskExecutorThread()) { - Object currentValue = _attributes.get(name); + if (changeAttribute(name, expected, desired)) + { + attributeSet(name, expected, desired); + } + } + else + { + _taskExecutor.submitAndWait(new SetAttributeTask(this, name, expected, desired)); + } + return getAttribute(name); + } + + protected boolean changeAttribute(final String name, final Object expected, final Object desired) + { + synchronized (_attributes) + { + Object currentValue = getAttribute(name); if((currentValue == null && expected == null) || (currentValue != null && currentValue.equals(expected))) { _attributes.put(name, desired); - return desired; + return true; } else { - return currentValue; + return false; } } } public <T extends ConfiguredObject> T getParent(final Class<T> clazz) { - synchronized (this) + synchronized (_parents) { return (T) _parents.get(clazz); } @@ -258,7 +261,7 @@ abstract class AbstractAdapter implements ConfiguredObject protected <T extends ConfiguredObject> void addParent(Class<T> clazz, T parent) { - synchronized (this) + synchronized (_parents) { _parents.put(clazz, parent); } @@ -280,4 +283,40 @@ abstract class AbstractAdapter implements ConfiguredObject } } + @Override + public String toString() + { + return getClass().getSimpleName() + " [id=" + _id + ", name=" + getName() + "]"; + } + + @SuppressWarnings("unchecked") + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + if (_taskExecutor.isTaskExecutorThread()) + { + C child = addChild(childClass, attributes, otherParents); + if (child != null) + { + childAdded(child); + } + return child; + } + else + { + return (C)_taskExecutor.submitAndWait(new CreateChildTask(this, childClass, attributes, otherParents)); + } + } + + protected <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + throw new UnsupportedOperationException(); + } + + + protected TaskExecutor getTaskExecutor() + { + return _taskExecutor; + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java new file mode 100644 index 0000000000..ebd98f915d --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java @@ -0,0 +1,198 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.security.AccessControlException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.util.MapValueConverter; + +public abstract class AbstractKeyStoreAdapter extends AbstractAdapter +{ + private String _name; + private String _password; + + protected AbstractKeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes) + { + super(id, broker.getTaskExecutor()); + addParent(Broker.class, broker); + _name = MapValueConverter.getStringAttribute(TrustStore.NAME, attributes); + _password = MapValueConverter.getStringAttribute(TrustStore.PASSWORD, attributes); + setMandatoryAttribute(TrustStore.PATH, attributes); + setOptionalAttribute(TrustStore.TYPE, attributes); + setOptionalAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, attributes); + setOptionalAttribute(TrustStore.DESCRIPTION, attributes); + } + + @Override + public String getName() + { + return _name; + } + + @Override + public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException + { + throw new IllegalStateException(); + } + + @Override + public State getActualState() + { + return State.ACTIVE; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException + { + throw new IllegalStateException(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + throw new IllegalStateException(); + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, IllegalArgumentException + { + throw new IllegalStateException(); + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + return Collections.emptySet(); + } + + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + { + throw new UnsupportedOperationException(); + } + + @Override + public Object getAttribute(String name) + { + if(KeyStore.ID.equals(name)) + { + return getId(); + } + else if(KeyStore.NAME.equals(name)) + { + return getName(); + } + else if(KeyStore.STATE.equals(name)) + { + return getActualState(); + } + else if(KeyStore.DURABLE.equals(name)) + { + return isDurable(); + } + else if(KeyStore.LIFETIME_POLICY.equals(name)) + { + return getLifetimePolicy(); + } + else if(KeyStore.TIME_TO_LIVE.equals(name)) + { + return getTimeToLive(); + } + else if(KeyStore.CREATED.equals(name)) + { + + } + else if(KeyStore.UPDATED.equals(name)) + { + + } + else if(KeyStore.PASSWORD.equals(name)) + { + return null; // for security reasons we don't expose the password + } + return super.getAttribute(name); + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + return false; + } + + public String getPassword() + { + return _password; + } + + public void setPassword(String password) + { + _password = password; + } + + private void setMandatoryAttribute(String name, Map<String, Object> attributeValues) + { + changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues)); + } + + private void setOptionalAttribute(String name, Map<String, Object> attributeValues) + { + if (attributeValues.get(name) != null) + { + changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues)); + } + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java new file mode 100644 index 0000000000..ed4af9881f --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractPluginAdapter.java @@ -0,0 +1,152 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.security.AccessControlException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; + +public abstract class AbstractPluginAdapter extends AbstractAdapter implements Plugin +{ + + protected AbstractPluginAdapter(UUID id, Map<String, Object> defaults, Map<String, Object> attributes, TaskExecutor taskExecutor) + { + super(id, defaults, attributes, taskExecutor); + } + + @Override + public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException + { + throw new UnsupportedOperationException(); + } + + @Override + public State getActualState() + { + return null; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, AccessControlException, IllegalArgumentException + { + throw new UnsupportedOperationException(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + throw new UnsupportedOperationException(); + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + throw new UnsupportedOperationException(); + } + + @Override + public Statistics getStatistics() + { + return null; + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + return Collections.emptyList(); + } + + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + throw new UnsupportedOperationException(); + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (ID.equals(name)) + { + return getId(); + } + else if (STATE.equals(name)) + { + return getActualState(); + } + else if (DURABLE.equals(name)) + { + return isDurable(); + } + else if (LIFETIME_POLICY.equals(name)) + { + return getLifetimePolicy(); + } + else if (TIME_TO_LIVE.equals(name)) + { + return getTimeToLive(); + } + else if (CREATED.equals(name)) + { + + } + else if (UPDATED.equals(name)) + { + + } + return super.getAttribute(name); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java new file mode 100644 index 0000000000..2f7e89bb2b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.security.GeneralSecurityException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import javax.net.ssl.SSLContext; + +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.messages.BrokerMessages; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.TrustStore; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.protocol.AmqpProtocolVersion; +import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory; +import org.apache.qpid.ssl.SSLContextFactory; +import org.apache.qpid.transport.NetworkTransportConfiguration; +import org.apache.qpid.transport.network.IncomingNetworkTransport; + +public class AmqpPortAdapter extends PortAdapter +{ + private final Broker _broker; + private IncomingNetworkTransport _transport; + + public AmqpPortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaultAttributes, TaskExecutor taskExecutor) + { + super(id, broker, attributes, defaultAttributes, taskExecutor); + _broker = broker; + } + + @Override + protected void onActivate() + { + Collection<Transport> transports = getTransports(); + Set<AmqpProtocolVersion> supported = convertFromModelProtocolsToAmqp(getProtocols()); + + SSLContext sslContext = null; + if (transports.contains(Transport.SSL)) + { + sslContext = createSslContext(); + } + + AmqpProtocolVersion defaultSupportedProtocolReply = getDefaultAmqpSupportedReply(); + + String bindingAddress = (String) getAttribute(Port.BINDING_ADDRESS); + if (WILDCARD_ADDRESS.equals(bindingAddress)) + { + bindingAddress = null; + } + Integer port = (Integer) getAttribute(Port.PORT); + InetSocketAddress bindingSocketAddress = null; + if ( bindingAddress == null ) + { + bindingSocketAddress = new InetSocketAddress(port); + } + else + { + bindingSocketAddress = new InetSocketAddress(bindingAddress, port); + } + + final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration( + bindingSocketAddress, (Boolean)getAttribute(TCP_NO_DELAY), + (Integer)getAttribute(SEND_BUFFER_SIZE), (Integer)getAttribute(RECEIVE_BUFFER_SIZE), + (Boolean)getAttribute(NEED_CLIENT_AUTH), (Boolean)getAttribute(WANT_CLIENT_AUTH)); + + _transport = org.apache.qpid.transport.network.Transport.getIncomingTransportInstance(); + final MultiVersionProtocolEngineFactory protocolEngineFactory = new MultiVersionProtocolEngineFactory( + _broker, supported, defaultSupportedProtocolReply); + + _transport.accept(settings, protocolEngineFactory, sslContext); + CurrentActor.get().message(BrokerMessages.LISTENING(getTransports().toString(), getPort())); + } + + @Override + protected void onStop() + { + if (_transport != null) + { + CurrentActor.get().message(BrokerMessages.SHUTTING_DOWN(getTransports().toString(), getPort())); + _transport.close(); + } + } + + private Set<AmqpProtocolVersion> convertFromModelProtocolsToAmqp(Collection<Protocol> modelProtocols) + { + Set<AmqpProtocolVersion> amqpProtocols = new HashSet<AmqpProtocolVersion>(); + for (Protocol protocol : modelProtocols) + { + amqpProtocols.add(protocol.toAmqpProtocolVersion()); + } + return amqpProtocols; + } + + private SSLContext createSslContext() + { + KeyStore keyStore = _broker.getDefaultKeyStore(); + if (keyStore == null) + { + throw new IllegalConfigurationException("SSL was requested on AMQP port '" + + this.getName() + "' but no key store defined"); + } + + TrustStore trustStore = _broker.getDefaultTrustStore(); + if (((Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH)) && trustStore == null) + { + throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '" + + this.getName() + "' but no trust store defined"); + } + + String keystorePath = (String)keyStore.getAttribute(KeyStore.PATH); + String keystorePassword = keyStore.getPassword(); + String keystoreType = (String)keyStore.getAttribute(KeyStore.TYPE); + String keyManagerFactoryAlgorithm = (String)keyStore.getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM); + String certAlias = (String)keyStore.getAttribute(KeyStore.CERTIFICATE_ALIAS); + + final SSLContext sslContext; + try + { + if(trustStore != null) + { + String trustStorePassword = trustStore.getPassword(); + String trustStoreType = (String)trustStore.getAttribute(TrustStore.TYPE); + String trustManagerFactoryAlgorithm = (String)trustStore.getAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM); + String trustStorePath = (String)trustStore.getAttribute(TrustStore.PATH); + + sslContext = SSLContextFactory.buildClientContext(trustStorePath, + trustStorePassword, + trustStoreType, + trustManagerFactoryAlgorithm, + keystorePath, + keystorePassword, keystoreType, keyManagerFactoryAlgorithm, + certAlias); + } + else + { + sslContext = SSLContextFactory.buildServerContext(keystorePath, keystorePassword, keystoreType, keyManagerFactoryAlgorithm); + } + } + catch (GeneralSecurityException e) + { + throw new RuntimeException("Unable to create SSLContext for key or trust store", e); + } + catch (IOException e) + { + throw new RuntimeException("Unable to create SSLContext - unable to load key/trust store", e); + } + return sslContext; + } + + private AmqpProtocolVersion getDefaultAmqpSupportedReply() + { + String defaultAmqpSupportedReply = System.getProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY); + if (defaultAmqpSupportedReply != null) + { + return AmqpProtocolVersion.valueOf(defaultAmqpSupportedReply); + } + return null; + } + + + class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration + { + private final InetSocketAddress _bindingSocketAddress; + private final Boolean _tcpNoDelay; + private final Integer _sendBufferSize; + private final Integer _receiveBufferSize; + private final boolean _needClientAuth; + private final boolean _wantClientAuth; + + public ServerNetworkTransportConfiguration( + InetSocketAddress bindingSocketAddress, boolean tcpNoDelay, + int sendBufferSize, int receiveBufferSize, + boolean needClientAuth, boolean wantClientAuth) + { + _bindingSocketAddress = bindingSocketAddress; + _tcpNoDelay = tcpNoDelay; + _sendBufferSize = sendBufferSize; + _receiveBufferSize = receiveBufferSize; + _needClientAuth = needClientAuth; + _wantClientAuth = wantClientAuth; + } + + @Override + public boolean wantClientAuth() + { + return _wantClientAuth; + } + + @Override + public boolean needClientAuth() + { + return _needClientAuth; + } + + @Override + public Boolean getTcpNoDelay() + { + return _tcpNoDelay; + } + + @Override + public Integer getSendBufferSize() + { + return _sendBufferSize; + } + + @Override + public Integer getReceiveBufferSize() + { + return _receiveBufferSize; + } + + @Override + public InetSocketAddress getAddress() + { + return _bindingSocketAddress; + } + }; +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java index 8c2bc98ba7..ac4b0255d5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java @@ -29,38 +29,50 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; + import javax.security.auth.login.AccountNotFoundException; import org.apache.log4j.Logger; -import org.apache.qpid.server.model.*; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.IllegalStateTransitionException; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.User; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.security.SecurityManager; public abstract class AuthenticationProviderAdapter<T extends AuthenticationManager> extends AbstractAdapter implements AuthenticationProvider { private static final Logger LOGGER = Logger.getLogger(AuthenticationProviderAdapter.class); - private final BrokerAdapter _broker; private final T _authManager; + protected final Broker _broker; - private AuthenticationProviderAdapter(BrokerAdapter brokerAdapter, - final T authManager) - { - super(UUIDGenerator.generateRandomUUID()); - _broker = brokerAdapter; - _authManager = authManager; - } + private GroupPrincipalAccessor _groupAccessor; - public static AuthenticationProviderAdapter createAuthenticationProviderAdapter(BrokerAdapter brokerAdapter, - final AuthenticationManager authManager) + private Object _type; + + private AuthenticationProviderAdapter(UUID id, Broker broker, final T authManager, Map<String, Object> attributes) { - return authManager instanceof PrincipalDatabaseAuthenticationManager - ? new PrincipalDatabaseAuthenticationManagerAdapter(brokerAdapter, (PrincipalDatabaseAuthenticationManager) authManager) - : new SimpleAuthenticationProviderAdapter(brokerAdapter, authManager); + super(id, null, attributes, broker.getTaskExecutor()); + _authManager = authManager; + _broker = broker; + _type = authManager instanceof PrincipalDatabaseAuthenticationManager? PrincipalDatabaseAuthenticationManager.class.getSimpleName() : AuthenticationManager.class.getSimpleName() ; + addParent(Broker.class, broker); } T getAuthManager() @@ -77,7 +89,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana @Override public String getName() { - return _authManager.getClass().getSimpleName(); + return (String)getAttribute(AuthenticationProvider.NAME); } @Override @@ -147,7 +159,7 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { if(TYPE.equals(name)) { - return _authManager.getClass().getSimpleName(); + return _type; } else if(CREATED.equals(name)) { @@ -165,10 +177,6 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { return LifetimePolicy.PERMANENT; } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { return State.ACTIVE; // TODO @@ -191,44 +199,86 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, - Map<String, Object> attributes, - ConfiguredObject... otherParents) + public boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, AccessControlException { - return null; + if(desiredState == State.DELETED) + { + return true; + } + else if(desiredState == State.ACTIVE) + { + if (_groupAccessor == null) + { + throw new IllegalStateTransitionException("Cannot transit into ACTIVE state with null group accessor!"); + } + _authManager.initialise(); + return true; + } + else if(desiredState == State.STOPPED) + { + _authManager.close(); + return true; + } + return false; } - private static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager> + @Override + public SubjectCreator getSubjectCreator() { + return new SubjectCreator(_authManager, _groupAccessor); + } + + public void setGroupAccessor(GroupPrincipalAccessor groupAccessor) + { + _groupAccessor = groupAccessor; + } + + public static class SimpleAuthenticationProviderAdapter extends AuthenticationProviderAdapter<AuthenticationManager> + { + public SimpleAuthenticationProviderAdapter( - BrokerAdapter brokerAdapter, AuthenticationManager authManager) + UUID id, Broker broker, AuthenticationManager authManager, Map<String, Object> attributes) + { + super(id, broker,authManager, attributes); + } + + @Override + public <C extends ConfiguredObject> C createChild(Class<C> childClass, + Map<String, Object> attributes, + ConfiguredObject... otherParents) { - super(brokerAdapter,authManager); + throw new UnsupportedOperationException(); } } - private static class PrincipalDatabaseAuthenticationManagerAdapter + public static class PrincipalDatabaseAuthenticationManagerAdapter extends AuthenticationProviderAdapter<PrincipalDatabaseAuthenticationManager> implements PasswordCredentialManagingAuthenticationProvider { public PrincipalDatabaseAuthenticationManagerAdapter( - BrokerAdapter brokerAdapter, PrincipalDatabaseAuthenticationManager authManager) + UUID id, Broker broker, PrincipalDatabaseAuthenticationManager authManager, Map<String, Object> attributes) { - super(brokerAdapter, authManager); + super(id, broker, authManager, attributes); } @Override public boolean createUser(String username, String password, Map<String, String> attributes) { - return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray()); + if(getSecurityManager().authoriseUserOperation(Operation.CREATE, username)) + { + return getPrincipalDatabase().createPrincipal(new UsernamePrincipal(username), password.toCharArray()); + } + else + { + throw new AccessControlException("Do not have permission to create new user"); + } } @Override public void deleteUser(String username) throws AccountNotFoundException { - if(getSecurityManager().authoriseMethod(Operation.DELETE, - "UserManagement", - "deleteUser")) + if(getSecurityManager().authoriseUserOperation(Operation.DELETE, username)) { getPrincipalDatabase().deletePrincipal(new UsernamePrincipal(username)); @@ -239,9 +289,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } } - private org.apache.qpid.server.security.SecurityManager getSecurityManager() + private SecurityManager getSecurityManager() { - return ApplicationRegistry.getInstance().getSecurityManager(); + return _broker.getSecurityManager(); } private PrincipalDatabase getPrincipalDatabase() @@ -252,18 +302,13 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana @Override public void setPassword(String username, String password) throws AccountNotFoundException { - getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray()); - } - - public void reload() throws IOException - { - if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "reload")) + if(getSecurityManager().authoriseUserOperation(Operation.UPDATE, username)) { - getPrincipalDatabase().reload(); + getPrincipalDatabase().updatePassword(new UsernamePrincipal(username), password.toCharArray()); } else { - throw new AccessControlException("Do not have permission to reload principal database"); + throw new AccessControlException("Do not have permission to set password"); } } @@ -274,34 +319,41 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana Map<String, Map<String,String>> users = new HashMap<String, Map<String, String>>(); for(Principal principal : getPrincipalDatabase().getUsers()) { - users.put(principal.getName(), Collections.EMPTY_MAP); + users.put(principal.getName(), Collections.<String, String>emptyMap()); } return users; } + public void reload() throws IOException + { + getPrincipalDatabase().reload(); + } + @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == User.class) { - Principal p = new UsernamePrincipal((String) attributes.get("name")); - if(getSecurityManager().authoriseMethod(Operation.UPDATE, "UserManagement", "createUser")) + String username = (String) attributes.get("name"); + String password = (String) attributes.get("password"); + Principal p = new UsernamePrincipal(username); + + if(createUser(username, password,null)) { - if(getPrincipalDatabase().createPrincipal(p, ((String)attributes.get("password")).toCharArray())) - { - return (C) new PrincipalAdapter(p); - } + @SuppressWarnings("unchecked") + C pricipalAdapter = (C) new PrincipalAdapter(p, getTaskExecutor()); + return pricipalAdapter; } else { - throw new AccessControlException("Do not have permission to create a new user"); + //TODO? Silly interface on the PrincipalDatabase at fault + throw new RuntimeException("Failed to create user"); } - } - return super.createChild(childClass, attributes, otherParents); + return super.addChild(childClass, attributes, otherParents); } @Override @@ -313,9 +365,11 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana Collection<User> principals = new ArrayList<User>(users.size()); for(Principal user : users) { - principals.add(new PrincipalAdapter(user)); + principals.add(new PrincipalAdapter(user, getTaskExecutor())); } - return (Collection<C>) Collections.unmodifiableCollection(principals); + @SuppressWarnings("unchecked") + Collection<C> unmodifiablePrincipals = (Collection<C>) Collections.unmodifiableCollection(principals); + return unmodifiablePrincipals; } else { @@ -328,20 +382,14 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana private final Principal _user; - public PrincipalAdapter(Principal user) + public PrincipalAdapter(Principal user, TaskExecutor taskExecutor) { - super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName())); + super(UUIDGenerator.generateUserUUID(PrincipalDatabaseAuthenticationManagerAdapter.this.getName(), user.getName()), taskExecutor); _user = user; } @Override - public String getPassword() - { - return null; - } - - @Override public void setPassword(String password) { try @@ -445,6 +493,10 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { return getId(); } + else if(PASSWORD.equals(name)) + { + return null; // for security reasons we don't expose the password + } else if(NAME.equals(name)) { return getName(); @@ -453,20 +505,19 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana } @Override - public Object setAttribute(String name, Object expected, Object desired) + public boolean changeAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { if(name.equals(PASSWORD)) { setPassword((String)desired); + return true; } - return super.setAttribute(name, - expected, - desired); + return super.changeAttribute(name, expected, desired); } @Override - public State setDesiredState(State currentState, State desiredState) + protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException { if(desiredState == State.DELETED) @@ -479,9 +530,9 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana { LOGGER.warn("Failed to delete user " + _user, e); } - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java new file mode 100644 index 0000000000..e5108ebbcf --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java @@ -0,0 +1,77 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.PrincipalDatabaseAuthenticationManagerAdapter; +import org.apache.qpid.server.model.adapter.AuthenticationProviderAdapter.SimpleAuthenticationProviderAdapter; + +public class AuthenticationProviderFactory +{ + private final Iterable<AuthenticationManagerFactory> _factories; + + public AuthenticationProviderFactory(QpidServiceLoader<AuthenticationManagerFactory> authManagerFactoryServiceLoader) + { + _factories = authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class); + } + + /** + * Creates {@link AuthenticationProvider} for given ID, {@link Broker} and attributes. + * <p> + * The configured {@link AuthenticationManagerFactory}'s are used to try to create the {@link AuthenticationProvider}. + * The first non-null instance is returned. The factories are used in non-deterministic order. + * @param groupPrincipalAccessor TODO + */ + public AuthenticationProvider create(UUID id, Broker broker, Map<String, Object> attributes, GroupPrincipalAccessor groupPrincipalAccessor) + { + for (AuthenticationManagerFactory factory : _factories) + { + AuthenticationManager manager = factory.createInstance(attributes); + if (manager != null) + { + AuthenticationProviderAdapter<?> authenticationProvider; + if (manager instanceof PrincipalDatabaseAuthenticationManager) + { + authenticationProvider = new PrincipalDatabaseAuthenticationManagerAdapter(id, broker, + (PrincipalDatabaseAuthenticationManager) manager, attributes); + } + else + { + authenticationProvider = new SimpleAuthenticationProviderAdapter(id, broker, manager, attributes); + } + authenticationProvider.setGroupAccessor(groupPrincipalAccessor); + return authenticationProvider; + } + } + + throw new IllegalArgumentException("No authentication provider factory found for configuration attributes " + attributes); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java index abd3160686..eb2d0dd7e2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BindingAdapter.java @@ -48,7 +48,7 @@ final class BindingAdapter extends AbstractAdapter implements Binding ExchangeAdapter exchangeAdapter, QueueAdapter queueAdapter) { - super(binding.getId()); + super(binding.getId(), queueAdapter.getTaskExecutor()); _binding = binding; _exchange = exchangeAdapter; _queue = queueAdapter; @@ -206,27 +206,20 @@ final class BindingAdapter extends AbstractAdapter implements Binding } @Override - public Object setAttribute(final String name, final Object expected, final Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - } - - @Override public Collection<String> getAttributeNames() { return Binding.AVAILABLE_ATTRIBUTES; } @Override - public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException, + protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException { if (desiredState == State.DELETED) { delete(); - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index f1cce2d45c..533ecfe937 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -21,82 +21,211 @@ package org.apache.qpid.server.model.adapter; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; +import java.util.UUID; + +import javax.net.ssl.KeyManagerFactory; + +import org.apache.log4j.Logger; import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.actors.BrokerActor; +import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.KeyStore; import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; -import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; -import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; -import org.apache.qpid.server.transport.QpidAcceptor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.group.FileGroupManager; +import org.apache.qpid.server.security.group.GroupManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.util.MapValueConverter; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHostRegistry.RegistryChangeListener, - IApplicationRegistry.PortBindingListener, - IAuthenticationManagerRegistry.RegistryChangeListener +public class BrokerAdapter extends AbstractAdapter implements Broker, ConfigurationChangeListener { - - private final IApplicationRegistry _applicationRegistry; - private String _name; - private final Map<org.apache.qpid.server.virtualhost.VirtualHost, VirtualHostAdapter> _vhostAdapters = - new HashMap<org.apache.qpid.server.virtualhost.VirtualHost, VirtualHostAdapter>(); - private final StatisticsAdapter _statistics; - private final Map<QpidAcceptor, PortAdapter> _portAdapters = new HashMap<QpidAcceptor, PortAdapter>(); - private Collection<HTTPPortAdapter> _httpManagementPorts; - - private final Map<AuthenticationManager, AuthenticationProviderAdapter> _authManagerAdapters = - new HashMap<AuthenticationManager, AuthenticationProviderAdapter>(); - - - public BrokerAdapter(final IApplicationRegistry instance) - { - super(UUIDGenerator.generateRandomUUID()); - _applicationRegistry = instance; - _name = "Broker"; - _statistics = new StatisticsAdapter(instance); - - instance.getVirtualHostRegistry().addRegistryChangeListener(this); - populateVhosts(); - instance.addPortBindingListener(this); - populatePorts(); - instance.addRegistryChangeListener(this); - populateAuthenticationManagers(); - } - - private void populateVhosts() - { - synchronized(_vhostAdapters) - { - Collection<org.apache.qpid.server.virtualhost.VirtualHost> actualVhosts = - _applicationRegistry.getVirtualHostRegistry().getVirtualHosts(); - for(org.apache.qpid.server.virtualhost.VirtualHost vh : actualVhosts) - { - if(!_vhostAdapters.containsKey(vh)) - { - _vhostAdapters.put(vh, new VirtualHostAdapter(this, vh)); - } - } - + private static final Logger LOGGER = Logger.getLogger(BrokerAdapter.class); + + @SuppressWarnings("serial") + public static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{ + put(ALERT_THRESHOLD_MESSAGE_AGE, Long.class); + put(ALERT_THRESHOLD_MESSAGE_COUNT, Long.class); + put(ALERT_THRESHOLD_QUEUE_DEPTH, Long.class); + put(ALERT_THRESHOLD_MESSAGE_SIZE, Long.class); + put(ALERT_REPEAT_GAP, Long.class); + put(FLOW_CONTROL_SIZE_BYTES, Long.class); + put(FLOW_CONTROL_RESUME_SIZE_BYTES, Long.class); + put(HOUSEKEEPING_CHECK_PERIOD, Long.class); + + put(DEAD_LETTER_QUEUE_ENABLED, Boolean.class); + put(STATISTICS_REPORTING_RESET_ENABLED, Boolean.class); + + put(MAXIMUM_DELIVERY_ATTEMPTS, Integer.class); + put(SESSION_COUNT_LIMIT, Integer.class); + put(HEART_BEAT_DELAY, Integer.class); + put(STATISTICS_REPORTING_PERIOD, Integer.class); + + put(ACL_FILE, String.class); + put(NAME, String.class); + put(DEFAULT_VIRTUAL_HOST, String.class); + put(DEFAULT_AUTHENTICATION_PROVIDER, String.class); + + put(KEY_STORE_PATH, String.class); + put(KEY_STORE_PASSWORD, String.class); + put(KEY_STORE_CERT_ALIAS, String.class); + put(TRUST_STORE_PATH, String.class); + put(TRUST_STORE_PASSWORD, String.class); + put(GROUP_FILE, String.class); + }}); + + public static final int DEFAULT_STATISTICS_REPORTING_PERIOD = 0; + public static final boolean DEFAULT_STATISTICS_REPORTING_RESET_ENABLED = false; + public static final long DEFAULT_ALERT_REPEAT_GAP = 30000l; + public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_AGE = 0l; + public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_COUNT = 0l; + public static final long DEFAULT_ALERT_THRESHOLD_MESSAGE_SIZE = 0l; + public static final long DEFAULT_ALERT_THRESHOLD_QUEUE_DEPTH = 0l; + public static final boolean DEFAULT_DEAD_LETTER_QUEUE_ENABLED = false; + public static final int DEFAULT_MAXIMUM_DELIVERY_ATTEMPTS = 0; + public static final long DEFAULT_FLOW_CONTROL_RESUME_SIZE_BYTES = 0l; + public static final long DEFAULT_FLOW_CONTROL_SIZE_BYTES = 0l; + public static final long DEFAULT_HOUSEKEEPING_CHECK_PERIOD = 30000l; + public static final int DEFAULT_HEART_BEAT_DELAY = 0; + public static final int DEFAULT_SESSION_COUNT_LIMIT = 256; + public static final String DEFAULT_NAME = "QpidBroker"; + private static final String DEFAULT_KEY_STORE_NAME = "defaultKeyStore"; + private static final String DEFAULT_TRUST_STORE_NAME = "defaultTrustStore"; + private static final String DEFAULT_GROUP_PROFIDER_NAME = "defaultGroupProvider"; + + private static final String DUMMY_PASSWORD_MASK = "********"; + + @SuppressWarnings("serial") + private static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>(){{ + put(Broker.STATISTICS_REPORTING_PERIOD, DEFAULT_STATISTICS_REPORTING_PERIOD); + put(Broker.STATISTICS_REPORTING_RESET_ENABLED, DEFAULT_STATISTICS_REPORTING_RESET_ENABLED); + put(Broker.ALERT_REPEAT_GAP, DEFAULT_ALERT_REPEAT_GAP); + put(Broker.ALERT_THRESHOLD_MESSAGE_AGE, DEFAULT_ALERT_THRESHOLD_MESSAGE_AGE); + put(Broker.ALERT_THRESHOLD_MESSAGE_COUNT, DEFAULT_ALERT_THRESHOLD_MESSAGE_COUNT); + put(Broker.ALERT_THRESHOLD_MESSAGE_SIZE, DEFAULT_ALERT_THRESHOLD_MESSAGE_SIZE); + put(Broker.ALERT_THRESHOLD_QUEUE_DEPTH, DEFAULT_ALERT_THRESHOLD_QUEUE_DEPTH); + put(Broker.DEAD_LETTER_QUEUE_ENABLED, DEFAULT_DEAD_LETTER_QUEUE_ENABLED); + put(Broker.MAXIMUM_DELIVERY_ATTEMPTS, DEFAULT_MAXIMUM_DELIVERY_ATTEMPTS); + put(Broker.FLOW_CONTROL_RESUME_SIZE_BYTES, DEFAULT_FLOW_CONTROL_RESUME_SIZE_BYTES); + put(Broker.FLOW_CONTROL_SIZE_BYTES, DEFAULT_FLOW_CONTROL_SIZE_BYTES); + put(Broker.HOUSEKEEPING_CHECK_PERIOD, DEFAULT_HOUSEKEEPING_CHECK_PERIOD); + put(Broker.HEART_BEAT_DELAY, DEFAULT_HEART_BEAT_DELAY); + put(Broker.SESSION_COUNT_LIMIT, DEFAULT_SESSION_COUNT_LIMIT); + put(Broker.NAME, DEFAULT_NAME); + }}); + + + + + private final StatisticsGatherer _statisticsGatherer; + private final VirtualHostRegistry _virtualHostRegistry; + private final LogRecorder _logRecorder; + private final RootMessageLogger _rootMessageLogger; + private StatisticsAdapter _statistics; + + private final Map<String, VirtualHost> _vhostAdapters = new HashMap<String, VirtualHost>(); + private final Map<Integer, Port> _portAdapters = new HashMap<Integer, Port>(); + private final Map<String, AuthenticationProvider> _authenticationProviders = new HashMap<String, AuthenticationProvider>(); + private final Map<String, GroupProvider> _groupProviders = new HashMap<String, GroupProvider>(); + private final Map<UUID, ConfiguredObject> _plugins = new HashMap<UUID, ConfiguredObject>(); + private final Map<UUID, KeyStore> _keyStores = new HashMap<UUID, KeyStore>(); + private final Map<UUID, TrustStore> _trustStores = new HashMap<UUID, TrustStore>(); + + private final AuthenticationProviderFactory _authenticationProviderFactory; + private AuthenticationProvider _defaultAuthenticationProvider; + + private final PortFactory _portFactory; + private final SecurityManager _securityManager; + private final UUID _defaultKeyStoreId; + private final UUID _defaultTrustStoreId; + + public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, + LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory, + PortFactory portFactory, TaskExecutor taskExecutor) + { + super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); + _statisticsGatherer = statisticsGatherer; + _virtualHostRegistry = virtualHostRegistry; + _logRecorder = logRecorder; + _rootMessageLogger = rootMessageLogger; + _statistics = new StatisticsAdapter(statisticsGatherer); + _authenticationProviderFactory = authenticationProviderFactory; + _portFactory = portFactory; + _securityManager = new SecurityManager((String)getAttribute(ACL_FILE)); + + _defaultKeyStoreId = UUIDGenerator.generateBrokerChildUUID(KeyStore.class.getSimpleName(), DEFAULT_KEY_STORE_NAME); + _defaultTrustStoreId = UUIDGenerator.generateBrokerChildUUID(TrustStore.class.getSimpleName(), DEFAULT_TRUST_STORE_NAME); + createBrokerChildrenFromAttributes(); + } + + /* + * A temporary method to create broker children that can be only configured via broker attributes + */ + private void createBrokerChildrenFromAttributes() + { + String groupFile = (String) getAttribute(GROUP_FILE); + if (groupFile != null) + { + GroupManager groupManager = new FileGroupManager(groupFile); + UUID groupProviderId = UUIDGenerator.generateBrokerChildUUID(GroupProvider.class.getSimpleName(), + DEFAULT_GROUP_PROFIDER_NAME); + GroupProviderAdapter groupProviderAdapter = new GroupProviderAdapter(groupProviderId, groupManager, this); + addGroupProvider(groupProviderAdapter); + } + Map<String, Object> actualAttributes = getActualAttributes(); + String keyStorePath = (String) getAttribute(KEY_STORE_PATH); + if (keyStorePath != null) + { + Map<String, Object> keyStoreAttributes = new HashMap<String, Object>(); + keyStoreAttributes.put(KeyStore.NAME, DEFAULT_KEY_STORE_NAME); + keyStoreAttributes.put(KeyStore.PATH, keyStorePath); + keyStoreAttributes.put(KeyStore.PASSWORD, (String) actualAttributes.get(KEY_STORE_PASSWORD)); + keyStoreAttributes.put(KeyStore.TYPE, java.security.KeyStore.getDefaultType()); + keyStoreAttributes.put(KeyStore.CERTIFICATE_ALIAS, getAttribute(KEY_STORE_CERT_ALIAS)); + keyStoreAttributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm()); + KeyStoreAdapter KeyStoreAdapter = new KeyStoreAdapter(_defaultKeyStoreId, this, keyStoreAttributes); + addKeyStore(KeyStoreAdapter); + } + String trustStorePath = (String) getAttribute(TRUST_STORE_PATH); + if (trustStorePath != null) + { + Map<String, Object> trsustStoreAttributes = new HashMap<String, Object>(); + trsustStoreAttributes.put(TrustStore.NAME, DEFAULT_TRUST_STORE_NAME); + trsustStoreAttributes.put(TrustStore.PATH, trustStorePath); + trsustStoreAttributes.put(TrustStore.PASSWORD, (String) actualAttributes.get(TRUST_STORE_PASSWORD)); + trsustStoreAttributes.put(TrustStore.TYPE, java.security.KeyStore.getDefaultType()); + trsustStoreAttributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm()); + TrustStoreAdapter trustStore = new TrustStoreAdapter(_defaultTrustStoreId, this, trsustStoreAttributes); + addTrustStore(trustStore); } } - public Collection<VirtualHost> getVirtualHosts() { synchronized(_vhostAdapters) @@ -105,81 +234,57 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos } } - private void populatePorts() + + public Collection<Port> getPorts() { synchronized (_portAdapters) { - Map<InetSocketAddress, QpidAcceptor> acceptors = _applicationRegistry.getAcceptors(); - - for(Map.Entry<InetSocketAddress, QpidAcceptor> entry : acceptors.entrySet()) - { - if(!_portAdapters.containsKey(entry.getValue())) - { - _portAdapters.put(entry.getValue(), new PortAdapter(this, entry.getValue(), entry.getKey())); - } - } - if(_applicationRegistry.useHTTPManagement() || _applicationRegistry.useHTTPSManagement()) - { - ArrayList<HTTPPortAdapter> httpPorts = new ArrayList<HTTPPortAdapter>(); - if (_applicationRegistry.useHTTPManagement()) - { - httpPorts.add(new HTTPPortAdapter(this, _applicationRegistry.getHTTPManagementPort())); - } - if (_applicationRegistry.useHTTPSManagement()) - { - httpPorts.add(new HTTPPortAdapter(this, _applicationRegistry.getHTTPSManagementPort(), Protocol.HTTPS, Transport.SSL)); - } - _httpManagementPorts = Collections.unmodifiableCollection(httpPorts); - } + final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values()); + return ports; } } - public Collection<Port> getPorts() + public Collection<AuthenticationProvider> getAuthenticationProviders() { - synchronized (_portAdapters) + synchronized (_authenticationProviders) { - final ArrayList<Port> ports = new ArrayList<Port>(_portAdapters.values()); - if(_httpManagementPorts != null) - { - ports.addAll(_httpManagementPorts); - } - return ports; + return new ArrayList<AuthenticationProvider>(_authenticationProviders.values()); } } - private void populateAuthenticationManagers() + public AuthenticationProvider getAuthenticationProviderByName(String authenticationProviderName) { - synchronized (_authManagerAdapters) + Collection<AuthenticationProvider> providers = getAuthenticationProviders(); + for (AuthenticationProvider authenticationProvider : providers) { - IAuthenticationManagerRegistry authenticationManagerRegistry = - _applicationRegistry.getAuthenticationManagerRegistry(); - if(authenticationManagerRegistry != null) + if (authenticationProvider.getName().equals(authenticationProviderName)) { - Map<String, AuthenticationManager> authenticationManagers = - authenticationManagerRegistry.getAvailableAuthenticationManagers(); - - for(Map.Entry<String, AuthenticationManager> entry : authenticationManagers.entrySet()) - { - if(!_authManagerAdapters.containsKey(entry.getValue())) - { - _authManagerAdapters.put(entry.getValue(), - AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this, - entry.getValue())); - } - } + return authenticationProvider; } } + return null; } - public Collection<AuthenticationProvider> getAuthenticationProviders() + @Override + public AuthenticationProvider getDefaultAuthenticationProvider() + { + return _defaultAuthenticationProvider; + } + + public void setDefaultAuthenticationProvider(AuthenticationProvider provider) + { + _defaultAuthenticationProvider = provider; + } + + @Override + public Collection<GroupProvider> getGroupProviders() { - synchronized (_authManagerAdapters) + synchronized (_groupProviders) { - final ArrayList<AuthenticationProvider> authManagers = - new ArrayList<AuthenticationProvider>(_authManagerAdapters.values()); - return authManagers; + final ArrayList<GroupProvider> groupManagers = + new ArrayList<GroupProvider>(_groupProviders.values()); + return groupManagers; } - } public VirtualHost createVirtualHost(final String name, @@ -193,22 +298,29 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos return null; //TODO } - public VirtualHost createVirtualHost(final Map<String, Object> attributes) + private VirtualHost createVirtualHost(final Map<String, Object> attributes) throws AccessControlException, IllegalArgumentException { - return null; //TODO + final VirtualHostAdapter virtualHostAdapter = new VirtualHostAdapter(UUID.randomUUID(), attributes, this, + _statisticsGatherer, getTaskExecutor()); + addVirtualHost(virtualHostAdapter); + virtualHostAdapter.setDesiredState(State.INITIALISING, State.ACTIVE); + return virtualHostAdapter; } - public void deleteVirtualHost(final VirtualHost vhost) - throws AccessControlException, IllegalStateException + private boolean deleteVirtualHost(final VirtualHost vhost) throws AccessControlException, IllegalStateException { - //TODO - throw new UnsupportedOperationException("Not yet implemented"); + synchronized (_vhostAdapters) + { + _vhostAdapters.remove(vhost); + } + vhost.removeChangeListener(this); + return true; } public String getName() { - return _name; + return (String)getAttribute(NAME); } public String setName(final String currentName, final String desiredName) @@ -262,6 +374,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos return _statistics; } + @SuppressWarnings("unchecked") @Override public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) { @@ -277,12 +390,30 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos { return (Collection<C>) getAuthenticationProviders(); } + else if(clazz == GroupProvider.class) + { + return (Collection<C>) getGroupProviders(); + } + else if(clazz == KeyStore.class) + { + return (Collection<C>) getKeyStores(); + } + else if(clazz == TrustStore.class) + { + return (Collection<C>) getTrustStores(); + } + else if(clazz == Plugin.class) + { + return (Collection<C>) getPlugins(); + } return Collections.emptySet(); } + //TODO: ACL + @SuppressWarnings("unchecked") @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == VirtualHost.class) { @@ -302,111 +433,107 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos } } - private Port createPort(Map<String, Object> attributes) + private void addPort(Port port) { - // TODO - return null; + synchronized (_portAdapters) + { + int portNumber = port.getPort(); + if(_portAdapters.containsKey(portNumber)) + { + throw new IllegalArgumentException("Cannot add port " + port + " because port number " + portNumber + " already configured"); + } + _portAdapters.put(portNumber, port); + } + port.addChangeListener(this); } - private AuthenticationProvider createAuthenticationProvider(Map<String,Object> attributes) + private Port createPort(Map<String, Object> attributes) { - // TODO - return null; + Port port = _portFactory.createPort(UUID.randomUUID(), this, attributes); + addPort(port); + return port; } + private AuthenticationProvider createAuthenticationProvider(Map<String, Object> attributes) + { + // it's cheap to create the groupPrincipalAccessor on the fly + GroupPrincipalAccessor groupPrincipalAccessor = new GroupPrincipalAccessor(_groupProviders.values()); + + AuthenticationProvider authenticationProvider = _authenticationProviderFactory.create(UUID.randomUUID(), this, attributes, groupPrincipalAccessor); + addAuthenticationProvider(authenticationProvider); + return authenticationProvider; + } - public void virtualHostRegistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost) + /** + * @throws IllegalConfigurationException if an AuthenticationProvider with the same name already exists + */ + private void addAuthenticationProvider(AuthenticationProvider authenticationProvider) { - VirtualHostAdapter adapter = null; - synchronized (_vhostAdapters) + String name = authenticationProvider.getName(); + synchronized (_authenticationProviders) { - if(!_vhostAdapters.containsKey(virtualHost)) + if(_authenticationProviders.containsKey(name)) { - adapter = new VirtualHostAdapter(this, virtualHost); - _vhostAdapters.put(virtualHost, adapter); + throw new IllegalConfigurationException("Cannot add AuthenticationProvider because one with name " + name + " already exists"); } + _authenticationProviders.put(name, authenticationProvider); } - if(adapter != null) - { - childAdded(adapter); - } + authenticationProvider.addChangeListener(this); } - public void virtualHostUnregistered(org.apache.qpid.server.virtualhost.VirtualHost virtualHost) + private void addGroupProvider(GroupProvider groupProvider) { - VirtualHostAdapter adapter = null; - - synchronized (_vhostAdapters) - { - adapter = _vhostAdapters.remove(virtualHost); - } - if(adapter != null) + synchronized (_groupProviders) { - childRemoved(adapter); + String name = groupProvider.getName(); + if(_groupProviders.containsKey(name)) + { + throw new IllegalConfigurationException("Cannot add GroupProvider because one with name " + name + " already exists"); + } + _groupProviders.put(name, groupProvider); } + groupProvider.addChangeListener(this); } - @Override - public void authenticationManagerRegistered(AuthenticationManager authenticationManager) + private boolean deleteGroupProvider(GroupProvider object) + { + throw new UnsupportedOperationException("Not implemented yet!"); + } + + private void addKeyStore(KeyStore keyStore) { - AuthenticationProviderAdapter adapter = null; - synchronized (_authManagerAdapters) + synchronized (_keyStores) { - if(!_authManagerAdapters.containsKey(authenticationManager)) + if(_keyStores.containsKey(keyStore.getId())) { - adapter = - AuthenticationProviderAdapter.createAuthenticationProviderAdapter(this, authenticationManager); - _authManagerAdapters.put(authenticationManager, adapter); + throw new IllegalConfigurationException("Cannot add KeyStore because one with id " + keyStore.getId() + " already exists"); } + _keyStores.put(keyStore.getId(), keyStore); } - if(adapter != null) - { - childAdded(adapter); - } + keyStore.addChangeListener(this); } - @Override - public void authenticationManagerUnregistered(AuthenticationManager authenticationManager) + private boolean deleteKeyStore(KeyStore object) { - AuthenticationProviderAdapter adapter; - synchronized (_authManagerAdapters) - { - adapter = _authManagerAdapters.remove(authenticationManager); - } - if(adapter != null) - { - childRemoved(adapter); - } + throw new UnsupportedOperationException("Not implemented yet!"); } - - @Override - public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress) + private void addTrustStore(TrustStore trustStore) { - synchronized (_portAdapters) + synchronized (_trustStores) { - if(!_portAdapters.containsKey(acceptor)) + if(_trustStores.containsKey(trustStore.getId())) { - PortAdapter adapter = new PortAdapter(this, acceptor, bindAddress); - _portAdapters.put(acceptor, adapter); - childAdded(adapter); + throw new IllegalConfigurationException("Cannot add TrustStore because one with id " + trustStore.getId() + " already exists"); } + _trustStores.put(trustStore.getId(), trustStore); } + trustStore.addChangeListener(this); } - @Override - public void unbound(QpidAcceptor acceptor) + private boolean deleteTrustStore(TrustStore object) { - PortAdapter adapter = null; - - synchronized (_portAdapters) - { - adapter = _portAdapters.remove(acceptor); - } - if(adapter != null) - { - childRemoved(adapter); - } + throw new UnsupportedOperationException("Not implemented yet!"); } @Override @@ -422,10 +549,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos { return getId(); } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { return State.ACTIVE; @@ -481,14 +604,316 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, VirtualHos { // TODO } + else if (DEFAULT_AUTHENTICATION_PROVIDER.equals(name)) + { + return _defaultAuthenticationProvider == null ? null : _defaultAuthenticationProvider.getName(); + } + else if (KEY_STORE_PASSWORD.equals(name)) + { + return DUMMY_PASSWORD_MASK; + } + else if (TRUST_STORE_PASSWORD.equals(name)) + { + return DUMMY_PASSWORD_MASK; + } + return super.getAttribute(name); + } - return super.getAttribute(name); //TODO - Implement. + private boolean deletePort(Port portAdapter) + { + Port removedPort = null; + synchronized (_portAdapters) + { + removedPort = _portAdapters.remove(portAdapter.getPort()); + } + return removedPort != null; + } + + private boolean deleteAuthenticationProvider(AuthenticationProvider authenticationProvider) + { + AuthenticationProvider removedAuthenticationProvider = null; + synchronized (_authenticationProviders) + { + removedAuthenticationProvider = _authenticationProviders.remove(authenticationProvider.getName()); + } + return removedAuthenticationProvider != null; + } + + private void addVirtualHost(VirtualHost virtualHost) + { + synchronized (_vhostAdapters) + { + String name = virtualHost.getName(); + if (_vhostAdapters.containsKey(name)) + { + throw new IllegalConfigurationException("Virtual host with name " + name + " is already specified!"); + } + _vhostAdapters.put(name, virtualHost); + } + virtualHost.addChangeListener(this); } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException + public boolean setState(State currentState, State desiredState) + { + if (desiredState == State.ACTIVE) + { + changeState(_groupProviders, currentState, State.ACTIVE, false); + changeState(_authenticationProviders, currentState, State.ACTIVE, false); + + CurrentActor.set(new BrokerActor(getRootMessageLogger())); + try + { + changeState(_vhostAdapters, currentState, State.ACTIVE, false); + } + finally + { + CurrentActor.remove(); + } + + changeState(_portAdapters, currentState,State.ACTIVE, false); + changeState(_plugins, currentState,State.ACTIVE, false); + return true; + } + else if (desiredState == State.STOPPED) + { + changeState(_plugins, currentState,State.STOPPED, true); + changeState(_portAdapters, currentState, State.STOPPED, true); + changeState(_vhostAdapters,currentState, State.STOPPED, true); + changeState(_authenticationProviders, currentState, State.STOPPED, true); + changeState(_groupProviders, currentState, State.STOPPED, true); + return true; + } + return false; + } + + private void changeState(Map<?, ? extends ConfiguredObject> configuredObjectMap, State currentState, State desiredState, boolean swallowException) + { + synchronized(configuredObjectMap) + { + Collection<? extends ConfiguredObject> adapters = configuredObjectMap.values(); + for (ConfiguredObject configuredObject : adapters) + { + if (State.ACTIVE.equals(desiredState) && State.QUIESCED.equals(configuredObject.getActualState())) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(configuredObject + " cannot be activated as it is " +State.QUIESCED); + } + continue; + } + try + { + configuredObject.setDesiredState(currentState, desiredState); + } + catch(RuntimeException e) + { + if (swallowException) + { + LOGGER.error("Failed to stop " + configuredObject, e); + } + else + { + throw e; + } + } + } + } + } + + @Override + public void stateChanged(ConfiguredObject object, State oldState, State newState) + { + if(newState == State.DELETED) + { + boolean childDeleted = false; + if(object instanceof AuthenticationProvider) + { + childDeleted = deleteAuthenticationProvider((AuthenticationProvider)object); + } + else if(object instanceof Port) + { + childDeleted = deletePort((Port)object); + } + else if(object instanceof VirtualHost) + { + childDeleted = deleteVirtualHost((VirtualHost)object); + } + else if(object instanceof GroupProvider) + { + childDeleted = deleteGroupProvider((GroupProvider)object); + } + else if(object instanceof KeyStore) + { + childDeleted = deleteKeyStore((KeyStore)object); + } + else if(object instanceof TrustStore) + { + childDeleted = deleteTrustStore((TrustStore)object); + } + if(childDeleted) + { + childRemoved(object); + } + } + } + + @Override + public void childAdded(ConfiguredObject object, ConfiguredObject child) + { + // no-op + } + + @Override + public void childRemoved(ConfiguredObject object, ConfiguredObject child) + { + // no-op + } + + @Override + public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue) + { + // no-op + } + + private void addPlugin(ConfiguredObject plugin) + { + synchronized(_plugins) + { + if (_plugins.containsKey(plugin.getId())) + { + throw new IllegalConfigurationException("Plugin with id '" + plugin.getId() + "' is already registered!"); + } + _plugins.put(plugin.getId(), plugin); + } + plugin.addChangeListener(this); + } + + + private Collection<ConfiguredObject> getPlugins() + { + synchronized(_plugins) + { + return Collections.unmodifiableCollection(_plugins.values()); + } + } + + public void recoverChild(ConfiguredObject object) + { + if(object instanceof AuthenticationProvider) + { + addAuthenticationProvider((AuthenticationProvider)object); + } + else if(object instanceof Port) + { + addPort((Port)object); + } + else if(object instanceof VirtualHost) + { + addVirtualHost((VirtualHost)object); + } + else if(object instanceof GroupProvider) + { + addGroupProvider((GroupProvider)object); + } + else if(object instanceof KeyStore) + { + addKeyStore((KeyStore)object); + } + else if(object instanceof TrustStore) + { + addTrustStore((TrustStore)object); + } + else if(object instanceof Plugin) + { + addPlugin(object); + } + else + { + throw new IllegalArgumentException("Attempted to recover unexpected type of configured object: " + object.getClass().getName()); + } + } + + @Override + public RootMessageLogger getRootMessageLogger() + { + return _rootMessageLogger; + } + + @Override + public SecurityManager getSecurityManager() + { + return _securityManager; + } + + @Override + public LogRecorder getLogRecorder() + { + return _logRecorder; + } + + @Override + public VirtualHost findVirtualHostByName(String name) + { + return _vhostAdapters.get(name); + } + + @Override + public SubjectCreator getSubjectCreator(SocketAddress localAddress) + { + InetSocketAddress inetSocketAddress = (InetSocketAddress)localAddress; + AuthenticationProvider provider = _defaultAuthenticationProvider; + Collection<Port> ports = getPorts(); + for (Port p : ports) + { + if (inetSocketAddress.getPort() == p.getPort()) + { + provider = p.getAuthenticationProvider(); + break; + } + } + return provider.getSubjectCreator(); + } + + @Override + public Collection<KeyStore> getKeyStores() + { + synchronized(_trustStores) + { + return Collections.unmodifiableCollection(_keyStores.values()); + } + } + + @Override + public Collection<TrustStore> getTrustStores() + { + synchronized(_trustStores) + { + return Collections.unmodifiableCollection(_trustStores.values()); + } + } + + @Override + public VirtualHostRegistry getVirtualHostRegistry() + { + return _virtualHostRegistry; + } + + @Override + public KeyStore getDefaultKeyStore() + { + return _keyStores.get(_defaultKeyStoreId); + } + + @Override + public TrustStore getDefaultTrustStore() + { + return _trustStores.get(_defaultTrustStoreId); + } + + @Override + public TaskExecutor getTaskExecutor() { - return super.setAttribute(name, expected, desired); //TODO - Implement. + return super.getTaskExecutor(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java index 5439f6a560..84f99e1f17 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConnectionAdapter.java @@ -38,6 +38,7 @@ import org.apache.qpid.server.model.Session; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.stats.StatisticsGatherer; @@ -50,9 +51,9 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection new HashMap<AMQSessionModel, SessionAdapter>(); private final Statistics _statistics; - public ConnectionAdapter(final AMQConnectionModel conn) + public ConnectionAdapter(final AMQConnectionModel conn, TaskExecutor taskExecutor) { - super(UUIDGenerator.generateRandomUUID()); + super(UUIDGenerator.generateRandomUUID(), taskExecutor); _connection = conn; _statistics = new ConnectionStatisticsAdapter(conn); } @@ -74,7 +75,7 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection { if(!_sessionAdapters.containsKey(session)) { - _sessionAdapters.put(session, new SessionAdapter(session)); + _sessionAdapters.put(session, new SessionAdapter(session, getTaskExecutor())); } } return new ArrayList<Session>(_sessionAdapters.values()); @@ -199,52 +200,6 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection } @Override - public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException - { - if(name.equals(CLIENT_ID)) - { - - } - else if(name.equals(CLIENT_VERSION)) - { - - } - else if(name.equals(INCOMING)) - { - - } - else if(name.equals(LOCAL_ADDRESS)) - { - - } - else if(name.equals(PRINCIPAL)) - { - - } - else if(name.equals(PROPERTIES)) - { - - } - else if(name.equals(REMOTE_ADDRESS)) - { - - } - else if(name.equals(REMOTE_PROCESS_NAME)) - { - - } - else if(name.equals(REMOTE_PROCESS_PID)) - { - - } - else if(name.equals(SESSION_COUNT_LIMIT)) - { - - } - return super.setAttribute(name, expected, desired); - } - - @Override public Collection<String> getAttributeNames() { final HashSet<String> attrNames = new HashSet<String>(super.getAttributeNames()); @@ -270,7 +225,8 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection } } - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == Session.class) { @@ -310,4 +266,11 @@ final class ConnectionAdapter extends AbstractAdapter implements Connection return super.getStatistic(name); } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO: add state management + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java index 031d518670..e6d3fab2f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ConsumerAdapter.java @@ -45,7 +45,7 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer queueAdapter.getName(), subscription.getSessionModel().getConnectionModel().getRemoteAddressString(), String.valueOf(subscription.getSessionModel().getChannelId()), - subscription.getConsumerName())); + subscription.getConsumerName()), queueAdapter.getTaskExecutor()); _subscription = subscription; _queue = queueAdapter; _statistics = new ConsumerStatistics(); @@ -108,13 +108,6 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer } @Override - public Object setAttribute(final String name, final Object expected, final Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - } - - @Override public Object getAttribute(final String name) { if(ID.equals(name)) @@ -222,4 +215,11 @@ public class ConsumerAdapter extends AbstractAdapter implements Consumer return null; // TODO - Implement } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO : Add state management + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java index df0f29fbc3..5d5f3f7378 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/ExchangeAdapter.java @@ -33,16 +33,15 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.model.IllegalStateTransitionException; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.Publisher; import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.util.MapValueConverter; import org.apache.qpid.server.virtualhost.VirtualHost; final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apache.qpid.server.exchange.Exchange.BindingListener @@ -57,7 +56,7 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa public ExchangeAdapter(final VirtualHostAdapter virtualHostAdapter, final org.apache.qpid.server.exchange.Exchange exchange) { - super(exchange.getId()); + super(exchange.getId(), virtualHostAdapter.getTaskExecutor()); _statistics = new ExchangeStatistics(); _vhost = virtualHostAdapter; _exchange = exchange; @@ -113,8 +112,8 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa throws AccessControlException, IllegalStateException { attributes = new HashMap<String, Object>(attributes); - String bindingKey = getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); - Map<String, Object> bindingArgs = getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.EMPTY_MAP); + String bindingKey = MapValueConverter.getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); + Map<String, Object> bindingArgs = MapValueConverter.getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.<String,Object>emptyMap()); attributes.remove(org.apache.qpid.server.model.Binding.NAME); attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS); @@ -257,7 +256,7 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa } @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == org.apache.qpid.server.model.Binding.class) { @@ -369,28 +368,20 @@ final class ExchangeAdapter extends AbstractAdapter implements Exchange, org.apa } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } - - @Override public Collection<String> getAttributeNames() { return AVAILABLE_ATTRIBUTES; } @Override - public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException, - AccessControlException + protected boolean setState(State currentState, State desiredState) { if (desiredState == State.DELETED) { delete(); - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } private class ExchangeStatistics implements Statistics diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java new file mode 100644 index 0000000000..0fa834bc28 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/GroupProviderAdapter.java @@ -0,0 +1,550 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.security.AccessControlException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Group; +import org.apache.qpid.server.model.GroupMember; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.IllegalStateTransitionException; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Statistics; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.group.GroupManager; +import org.apache.qpid.server.security.SecurityManager; + +public class GroupProviderAdapter extends AbstractAdapter implements + GroupProvider +{ + private final GroupManager _groupManager; + private final Broker _broker; + public GroupProviderAdapter(UUID id, GroupManager groupManager, Broker broker) + { + super(id, broker.getTaskExecutor()); + + if (groupManager == null) + { + throw new IllegalArgumentException("GroupManager must not be null"); + } + _groupManager = groupManager; + _broker = broker; + addParent(Broker.class, broker); + } + + @Override + public String getName() + { + return _groupManager.getClass().getSimpleName(); + } + + @Override + public String setName(String currentName, String desiredName) + throws IllegalStateException, AccessControlException + { + return null; + } + + @Override + public State getActualState() + { + return null; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, + LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + return null; + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + return 0; + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public Collection<String> getAttributeNames() + { + return GroupProvider.AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (TYPE.equals(name)) + { + return getName(); + } + else if (CREATED.equals(name)) + { + // TODO + } + else if (DURABLE.equals(name)) + { + return true; + } + else if (ID.equals(name)) + { + return getId(); + } + else if (LIFETIME_POLICY.equals(name)) + { + return LifetimePolicy.PERMANENT; + } + else if (NAME.equals(name)) + { + return getName(); + } + else if (STATE.equals(name)) + { + return State.ACTIVE; // TODO + } + else if (TIME_TO_LIVE.equals(name)) + { + // TODO + } + else if (UPDATED.equals(name)) + { + // TODO + } + return super.getAttribute(name); + } + + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, + Map<String, Object> attributes, ConfiguredObject... otherParents) + { + if (childClass == Group.class) + { + String groupName = (String) attributes.get(Group.NAME); + + if (getSecurityManager().authoriseGroupOperation(Operation.CREATE, groupName)) + { + _groupManager.createGroup(groupName); + return (C) new GroupAdapter(groupName, getTaskExecutor()); + } + else + { + throw new AccessControlException("Do not have permission" + + " to create new group"); + } + } + + throw new IllegalArgumentException( + "This group provider does not support creating children of type: " + + childClass); + } + + @SuppressWarnings("unchecked") + @Override + public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) + { + if (clazz == Group.class) + { + Set<Principal> groups = _groupManager.getGroupPrincipals(); + Collection<Group> principals = new ArrayList<Group>(groups.size()); + for (Principal group : groups) + { + principals.add(new GroupAdapter(group.getName(), getTaskExecutor())); + } + return (Collection<C>) Collections + .unmodifiableCollection(principals); + } + else + { + return null; + } + } + + private SecurityManager getSecurityManager() + { + return _broker.getSecurityManager(); + } + + private class GroupAdapter extends AbstractAdapter implements Group + { + private final String _group; + + public GroupAdapter(String group, TaskExecutor taskExecutor) + { + super(UUIDGenerator.generateGroupUUID(GroupProviderAdapter.this.getName(), group), taskExecutor); + _group = group; + + } + + @Override + public String getName() + { + return _group; + } + + @Override + public String setName(String currentName, String desiredName) + throws IllegalStateException, AccessControlException + { + throw new IllegalStateException("Names cannot be updated"); + } + + @Override + public State getActualState() + { + return State.ACTIVE; + } + + @Override + public boolean isDurable() + { + return true; + } + + @Override + public void setDurable(boolean durable) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + throw new IllegalStateException("Durability cannot be updated"); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, + LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + throw new IllegalStateException("LifetimePolicy cannot be updated"); + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + throw new IllegalStateException("ttl cannot be updated"); + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren( + Class<C> clazz) + { + if (clazz == GroupMember.class) + { + Set<Principal> usersInGroup = _groupManager + .getUserPrincipalsForGroup(_group); + Collection<GroupMember> members = new ArrayList<GroupMember>(); + for (Principal principal : usersInGroup) + { + members.add(new GroupMemberAdapter(principal.getName(), getTaskExecutor())); + } + return (Collection<C>) Collections + .unmodifiableCollection(members); + } + else + { + return null; + } + + } + + @Override + public <C extends ConfiguredObject> C addChild(Class<C> childClass, + Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + if (childClass == GroupMember.class) + { + String memberName = (String) attributes.get(GroupMember.NAME); + + if (getSecurityManager().authoriseGroupOperation(Operation.UPDATE, _group)) + { + _groupManager.addUserToGroup(memberName, _group); + return (C) new GroupMemberAdapter(memberName, getTaskExecutor()); + } + else + { + throw new AccessControlException("Do not have permission" + + " to add new group member"); + } + } + + throw new IllegalArgumentException( + "This group provider does not support creating children of type: " + + childClass); + } + + @Override + public Collection<String> getAttributeNames() + { + return Group.AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (ID.equals(name)) + { + return getId(); + } + else if (NAME.equals(name)) + { + return getName(); + } + return super.getAttribute(name); + } + + @Override + protected boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, AccessControlException + { + if (desiredState == State.DELETED) + { + if (getSecurityManager().authoriseGroupOperation(Operation.DELETE, _group)) + { + _groupManager.removeGroup(_group); + return true; + } + else + { + throw new AccessControlException("Do not have permission to delete group"); + } + } + + return false; + } + + private class GroupMemberAdapter extends AbstractAdapter implements + GroupMember + { + private String _memberName; + + public GroupMemberAdapter(String memberName, TaskExecutor taskExecutor) + { + super(UUIDGenerator.generateGroupMemberUUID(GroupProviderAdapter.this.getName(), _group, memberName), taskExecutor); + _memberName = memberName; + } + + @Override + public Collection<String> getAttributeNames() + { + return GroupMember.AVAILABLE_ATTRIBUTES; + } + + @Override + public Object getAttribute(String name) + { + if (ID.equals(name)) + { + return getId(); + } + else if (NAME.equals(name)) + { + return getName(); + } + return super.getAttribute(name); + } + + @Override + public String getName() + { + return _memberName; + } + + @Override + public String setName(String currentName, String desiredName) + throws IllegalStateException, AccessControlException + { + return null; + } + + @Override + public State getActualState() + { + return null; + } + + @Override + public boolean isDurable() + { + return false; + } + + @Override + public void setDurable(boolean durable) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return null; + } + + @Override + public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, + LifetimePolicy desired) throws IllegalStateException, + AccessControlException, IllegalArgumentException + { + return null; + } + + @Override + public long getTimeToLive() + { + return 0; + } + + @Override + public long setTimeToLive(long expected, long desired) + throws IllegalStateException, AccessControlException, + IllegalArgumentException + { + return 0; + } + + @Override + public Statistics getStatistics() + { + return NoStatistics.getInstance(); + } + + @Override + public <C extends ConfiguredObject> Collection<C> getChildren( + Class<C> clazz) + { + return null; + } + + @Override + public <C extends ConfiguredObject> C createChild( + Class<C> childClass, Map<String, Object> attributes, + ConfiguredObject... otherParents) + { + return null; + } + + @Override + protected boolean setState(State currentState, State desiredState) + throws IllegalStateTransitionException, + AccessControlException + { + if (desiredState == State.DELETED) + { + if (getSecurityManager().authoriseGroupOperation(Operation.UPDATE, _group)) + { + _groupManager.removeUserFromGroup(_memberName, _group); + return true; + } + else + { + throw new AccessControlException("Do not have permission to remove group member"); + } + } + return false; + } + + } + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + if (desiredState == State.ACTIVE) + { + return true; + } + else if (desiredState == State.STOPPED) + { + return true; + } + // TODO: DELETE state is ignored for now + // in case if we need to delete group provider, then we need AuthenticationProvider to be a change listener of it + // in order to remove deleted group provider from its group provider list + return false; + } + + public Set<Principal> getGroupPrincipalsForUser(String username) + { + return _groupManager.getGroupPrincipalsForUser(username); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java deleted file mode 100644 index 823d27160b..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/HTTPPortAdapter.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.model.adapter; - -import java.security.AccessControlException; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.Connection; -import org.apache.qpid.server.model.LifetimePolicy; -import org.apache.qpid.server.model.Port; -import org.apache.qpid.server.model.Protocol; -import org.apache.qpid.server.model.State; -import org.apache.qpid.server.model.Statistics; -import org.apache.qpid.server.model.Transport; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.model.VirtualHostAlias; - -public class HTTPPortAdapter extends AbstractAdapter implements Port -{ - private final BrokerAdapter _broker; - private final int _port; - private final Protocol _protocol; - private final Transport _transport; - - public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port) - { - this(brokerAdapter, port, Protocol.HTTP, Transport.TCP); - } - - public HTTPPortAdapter(BrokerAdapter brokerAdapter, int port, Protocol protocol, Transport transport) - { - super(UUIDGenerator.generateRandomUUID()); - _broker = brokerAdapter; - _port = port; - _protocol = protocol; - _transport = transport; - } - - @Override - public String getBindingAddress() - { - return "0.0.0.0"; - } - - @Override - public int getPort() - { - return _port; - } - - @Override - public Collection<Transport> getTransports() - { - return Collections.singleton(_transport); - } - - @Override - public void addTransport(Transport transport) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Transport removeTransport(Transport transport) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Collection<Protocol> getProtocols() - { - return Collections.singleton(_protocol); - } - - @Override - public void addProtocol(Protocol protocol) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Protocol removeProtocol(Protocol protocol) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Collection<VirtualHostAlias> getVirtualHostBindings() - { - return Collections.emptySet(); - } - - @Override - public Collection<Connection> getConnections() - { - return Collections.emptySet(); // TODO - Implement - } - - @Override - public String getName() - { - return getBindingAddress() + ":" + getPort(); // TODO - Implement - } - - @Override - public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public State getActualState() - { - return State.ACTIVE; - } - - @Override - public boolean isDurable() - { - return false; // TODO - Implement - } - - @Override - public void setDurable(boolean durable) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); - } - - @Override - public LifetimePolicy getLifetimePolicy() - { - return LifetimePolicy.PERMANENT; - } - - @Override - public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public long getTimeToLive() - { - return 0; // TODO - Implement - } - - @Override - public long setTimeToLive(long expected, long desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - throw new IllegalStateException(); // TODO - Implement - } - - @Override - public Statistics getStatistics() - { - return NoStatistics.getInstance(); - } - - @Override - public <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz) - { - if(clazz == Connection.class) - { - return (Collection<C>) getConnections(); - } - else - { - return Collections.emptySet(); - } - } - - @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) - { - throw new UnsupportedOperationException(); - } - - @Override - public Object getAttribute(String name) - { - if(ID.equals(name)) - { - return getId(); - } - else if(NAME.equals(name)) - { - return getName(); - } - else if(STATE.equals(name)) - { - return getActualState(); - } - else if(DURABLE.equals(name)) - { - return isDurable(); - } - else if(LIFETIME_POLICY.equals(name)) - { - return getLifetimePolicy(); - } - else if(TIME_TO_LIVE.equals(name)) - { - return getTimeToLive(); - } - else if(CREATED.equals(name)) - { - - } - else if(UPDATED.equals(name)) - { - - } - else if(BINDING_ADDRESS.equals(name)) - { - return getBindingAddress(); - } - else if(PORT.equals(name)) - { - return getPort(); - } - else if(PROTOCOLS.equals(name)) - { - return getProtocols(); - } - else if(TRANSPORTS.equals(name)) - { - return getTransports(); - } - - return super.getAttribute(name); //TODO - Implement - } - - @Override - public Collection<String> getAttributeNames() - { - return AVAILABLE_ATTRIBUTES; - } - - @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java index 4f143701af..113d895e62 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFCommand.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java @@ -18,37 +18,31 @@ * under the License. * */ +package org.apache.qpid.server.model.adapter; -package org.apache.qpid.qmf; +import java.util.Collection; +import java.util.Map; +import java.util.UUID; -import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.transport.codec.BBEncoder; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; -public abstract class QMFCommand +public class KeyStoreAdapter extends AbstractKeyStoreAdapter implements KeyStore { - private final QMFCommandHeader _header; - - protected QMFCommand(QMFCommandHeader header) - { - _header = header; - } - - - public void process(final VirtualHost virtualHost, final ServerMessage message) + public KeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes) { - throw new UnsupportedOperationException(); + super(id, broker, attributes); + if (attributes.get(CERTIFICATE_ALIAS) != null) + { + changeAttribute(CERTIFICATE_ALIAS, null, attributes.get(CERTIFICATE_ALIAS)); + } } - public void encode(BBEncoder encoder) + @Override + public Collection<String> getAttributeNames() { - _header.encode(encoder); - + return AVAILABLE_ATTRIBUTES; } - public QMFCommandHeader getHeader() - { - return _header; - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java index 7653fcc9b9..c4a531c923 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java @@ -21,7 +21,16 @@ package org.apache.qpid.server.model.adapter; +import java.security.AccessControlException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Connection; import org.apache.qpid.server.model.LifetimePolicy; @@ -30,119 +39,82 @@ import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.Transport; -import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostAlias; -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.server.transport.QpidAcceptor; - -import java.net.InetSocketAddress; -import java.security.AccessControlException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import org.apache.qpid.server.configuration.updater.TaskExecutor; public class PortAdapter extends AbstractAdapter implements Port { - private final BrokerAdapter _broker; - private final QpidAcceptor _acceptor; - private final InetSocketAddress _address; - private final Collection<Protocol> _protocols; - - public PortAdapter(BrokerAdapter brokerAdapter, QpidAcceptor acceptor, InetSocketAddress address) - { - super(UUIDGenerator.generateRandomUUID()); - _broker = brokerAdapter; - _acceptor = acceptor; - _address = address; - List<Protocol> protocols = new ArrayList<Protocol>(); + private final Broker _broker; + private AuthenticationProvider _authenticationProvider; - for(AmqpProtocolVersion pv : _acceptor.getSupported()) - { - switch(pv) - { - case v0_8: - protocols.add(Protocol.AMQP_0_8); - break; - case v0_9: - protocols.add(Protocol.AMQP_0_9); - break; - case v0_9_1: - protocols.add(Protocol.AMQP_0_9_1); - break; - case v0_10: - protocols.add(Protocol.AMQP_0_10); - break; - case v1_0_0: - protocols.add(Protocol.AMQP_1_0); - break; - } - } + /* + * TODO register PortAceptor as a listener. For supporting multiple + * protocols on the same port we need to introduce a special entity like + * PortAceptor which will be responsible for port binding/unbinding + */ + public PortAdapter(UUID id, Broker broker, Map<String, Object> attributes, Map<String, Object> defaults, TaskExecutor taskExecutor) + { + super(id, defaults, attributes, taskExecutor); + _broker = broker; - _protocols = Collections.unmodifiableCollection(protocols); + addParent(Broker.class, broker); } @Override public String getBindingAddress() { - return _address.getHostName(); + return (String)getAttribute(BINDING_ADDRESS); } @Override public int getPort() { - return _address.getPort(); + return (Integer)getAttribute(PORT); } + @SuppressWarnings("unchecked") @Override public Collection<Transport> getTransports() { - switch (_acceptor.getTransport()) - { - case TCP: - return Collections.singleton(Transport.TCP); - case SSL: - return Collections.singleton(Transport.SSL); - } - - return null; // TODO - Implement + return (Collection<Transport>)getAttribute(TRANSPORTS); } @Override public void addTransport(Transport transport) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public Transport removeTransport(Transport transport) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } + @SuppressWarnings("unchecked") @Override public Collection<Protocol> getProtocols() { - return _protocols; + return (Collection<Protocol>)getAttribute(PROTOCOLS); } @Override public void addProtocol(Protocol protocol) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public Protocol removeProtocol(Protocol protocol) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override @@ -165,31 +137,36 @@ public class PortAdapter extends AbstractAdapter implements Port @Override public Collection<Connection> getConnections() { - return null; // TODO - Implement + return null; } @Override public String getName() { - return getBindingAddress() + ":" + getPort(); // TODO - Implement + return (String)getAttribute(NAME); } @Override public String setName(String currentName, String desiredName) throws IllegalStateException, AccessControlException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public State getActualState() { - return State.ACTIVE; + State state = (State)super.getAttribute(STATE); + if (state == null) + { + return State.ACTIVE; + } + return state; } @Override public boolean isDurable() { - return false; // TODO - Implement + return false; } @Override @@ -209,20 +186,20 @@ public class PortAdapter extends AbstractAdapter implements Port public LifetimePolicy setLifetimePolicy(LifetimePolicy expected, LifetimePolicy desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override public long getTimeToLive() { - return 0; // TODO - Implement + return 0; } @Override public long setTimeToLive(long expected, long desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { - throw new IllegalStateException(); // TODO - Implement + throw new IllegalStateException(); } @Override @@ -257,10 +234,6 @@ public class PortAdapter extends AbstractAdapter implements Port { return getId(); } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { return getActualState(); @@ -285,36 +258,54 @@ public class PortAdapter extends AbstractAdapter implements Port { } - else if(BINDING_ADDRESS.equals(name)) - { - return getBindingAddress(); - } - else if(PORT.equals(name)) + return super.getAttribute(name); + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + + @Override + public boolean setState(State currentState, State desiredState) + { + if (desiredState == State.DELETED) { - return getPort(); + return true; } - else if(PROTOCOLS.equals(name)) + else if (desiredState == State.ACTIVE) { - return getProtocols(); + onActivate(); + return true; } - else if(TRANSPORTS.equals(name)) + else if (desiredState == State.STOPPED) { - return getTransports(); + onStop(); + return true; } + return false; + } - return super.getAttribute(name); //TODO - Implement + protected void onActivate() + { + // no-op: expected to be overridden by subclass } - @Override - public Collection<String> getAttributeNames() + protected void onStop() { - return AVAILABLE_ATTRIBUTES; + // no-op: expected to be overridden by subclass } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException + public AuthenticationProvider getAuthenticationProvider() + { + return _authenticationProvider; + } + + public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) { - return super.setAttribute(name, expected, desired); //TODO - Implement + _authenticationProvider = authenticationProvider; } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java new file mode 100644 index 0000000000..b7441b9f3b --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java @@ -0,0 +1,222 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.Protocol.ProtocolType; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.util.MapValueConverter; + +public class PortFactory +{ + public static final int DEFAULT_AMQP_SEND_BUFFER_SIZE = 262144; + public static final int DEFAULT_AMQP_RECEIVE_BUFFER_SIZE = 262144; + public static final boolean DEFAULT_AMQP_NEED_CLIENT_AUTH = false; + public static final boolean DEFAULT_AMQP_WANT_CLIENT_AUTH = false; + public static final boolean DEFAULT_AMQP_TCP_NO_DELAY = true; + public static final String DEFAULT_AMQP_BINDING = "*"; + public static final Transport DEFAULT_TRANSPORT = Transport.TCP; + + private final Collection<Protocol> _defaultProtocols; + + public PortFactory() + { + Set<Protocol> defaultProtocols = EnumSet.of(Protocol.AMQP_0_8, Protocol.AMQP_0_9, Protocol.AMQP_0_9_1, + Protocol.AMQP_0_10, Protocol.AMQP_1_0); + String excludedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES); + if (excludedProtocols != null) + { + String[] excludes = excludedProtocols.split(","); + for (String exclude : excludes) + { + Protocol protocol = Protocol.valueOf(exclude); + defaultProtocols.remove(protocol); + } + } + String includedProtocols = System.getProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES); + if (includedProtocols != null) + { + String[] includes = includedProtocols.split(","); + for (String include : includes) + { + Protocol protocol = Protocol.valueOf(include); + defaultProtocols.add(protocol); + } + } + _defaultProtocols = Collections.unmodifiableCollection(defaultProtocols); + } + + public Port createPort(UUID id, Broker broker, Map<String, Object> objectAttributes) + { + Map<String, Object> attributes = retrieveAttributes(objectAttributes); + + final Port port; + Map<String, Object> defaults = new HashMap<String, Object>(); + defaults.put(Port.TRANSPORTS, Collections.singleton(DEFAULT_TRANSPORT)); + Object portValue = attributes.get(Port.PORT); + if (portValue == null) + { + throw new IllegalConfigurationException("Port attribute is not specified for port: " + attributes); + } + if (isAmqpProtocol(attributes)) + { + Object binding = attributes.get(Port.BINDING_ADDRESS); + if (binding == null) + { + binding = DEFAULT_AMQP_BINDING; + defaults.put(Port.BINDING_ADDRESS, DEFAULT_AMQP_BINDING); + } + defaults.put(Port.NAME, binding + ":" + portValue); + defaults.put(Port.PROTOCOLS, _defaultProtocols); + defaults.put(Port.TCP_NO_DELAY, DEFAULT_AMQP_TCP_NO_DELAY); + defaults.put(Port.WANT_CLIENT_AUTH, DEFAULT_AMQP_WANT_CLIENT_AUTH); + defaults.put(Port.NEED_CLIENT_AUTH, DEFAULT_AMQP_NEED_CLIENT_AUTH); + defaults.put(Port.RECEIVE_BUFFER_SIZE, DEFAULT_AMQP_RECEIVE_BUFFER_SIZE); + defaults.put(Port.SEND_BUFFER_SIZE, DEFAULT_AMQP_SEND_BUFFER_SIZE); + port = new AmqpPortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor()); + } + else + { + @SuppressWarnings("unchecked") + Collection<Protocol> protocols = (Collection<Protocol>)attributes.get(Port.PROTOCOLS); + if (protocols.size() > 1) + { + throw new IllegalConfigurationException("Only one protocol can be used on non AMQP port"); + } + Protocol protocol = protocols.iterator().next(); + defaults.put(Port.NAME, portValue + "-" + protocol.name()); + port = new PortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor()); + } + return port; + } + + private Map<String, Object> retrieveAttributes(Map<String, Object> objectAttributes) + { + Map<String, Object> attributes = new HashMap<String, Object>(objectAttributes); + + if (objectAttributes.containsKey(Port.PROTOCOLS)) + { + final Set<Protocol> protocolSet = MapValueConverter.getEnumSetAttribute(Port.PROTOCOLS, objectAttributes, Protocol.class); + attributes.put(Port.PROTOCOLS, protocolSet); + } + + if (objectAttributes.containsKey(Port.TRANSPORTS)) + { + final Set<Transport> transportSet = MapValueConverter.getEnumSetAttribute(Port.TRANSPORTS, objectAttributes, + Transport.class); + attributes.put(Port.TRANSPORTS, transportSet); + } + + if (objectAttributes.containsKey(Port.PORT)) + { + Integer port = MapValueConverter.getIntegerAttribute(Port.PORT, objectAttributes); + attributes.put(Port.PORT, port); + } + + if (objectAttributes.containsKey(Port.TCP_NO_DELAY)) + { + boolean tcpNoDelay = MapValueConverter.getBooleanAttribute(Port.TCP_NO_DELAY, objectAttributes); + attributes.put(Port.TCP_NO_DELAY, tcpNoDelay); + } + + if (objectAttributes.containsKey(Port.RECEIVE_BUFFER_SIZE)) + { + int receiveBufferSize = MapValueConverter.getIntegerAttribute(Port.RECEIVE_BUFFER_SIZE, objectAttributes); + attributes.put(Port.RECEIVE_BUFFER_SIZE, receiveBufferSize); + } + + if (objectAttributes.containsKey(Port.SEND_BUFFER_SIZE)) + { + int sendBufferSize = MapValueConverter.getIntegerAttribute(Port.SEND_BUFFER_SIZE, objectAttributes); + attributes.put(Port.SEND_BUFFER_SIZE, sendBufferSize); + } + + if (objectAttributes.containsKey(Port.NEED_CLIENT_AUTH)) + { + boolean needClientAuth = MapValueConverter.getBooleanAttribute(Port.NEED_CLIENT_AUTH, objectAttributes); + attributes.put(Port.NEED_CLIENT_AUTH, needClientAuth); + } + + if (objectAttributes.containsKey(Port.WANT_CLIENT_AUTH)) + { + boolean wantClientAuth = MapValueConverter.getBooleanAttribute(Port.WANT_CLIENT_AUTH, objectAttributes); + attributes.put(Port.WANT_CLIENT_AUTH, wantClientAuth); + } + + if (objectAttributes.containsKey(Port.BINDING_ADDRESS)) + { + String binding = MapValueConverter.getStringAttribute(Port.BINDING_ADDRESS, objectAttributes); + attributes.put(Port.BINDING_ADDRESS, binding); + } + + if (objectAttributes.containsKey(Port.STATE)) + { + State state = MapValueConverter.getEnumAttribute(State.class, Port.STATE, objectAttributes); + attributes.put(Port.STATE, state); + } + return attributes; + } + + private boolean isAmqpProtocol(Map<String, Object> portAttributes) + { + @SuppressWarnings("unchecked") + Set<Protocol> protocols = (Set<Protocol>) portAttributes.get(Port.PROTOCOLS); + if (protocols == null || protocols.isEmpty()) + { + // defaulting to AMQP if protocol is not specified + return true; + } + + Set<ProtocolType> protocolTypes = new HashSet<ProtocolType>(); + for (Protocol protocolObject : protocols) + { + protocolTypes.add(protocolObject.getProtocolType()); + } + + if (protocolTypes.size() > 1) + { + throw new IllegalConfigurationException("Found different protocol types '" + protocolTypes + + "' on port configuration: " + portAttributes); + } + + return protocolTypes.contains(ProtocolType.AMQP); + } + + public Collection<Protocol> getDefaultProtocols() + { + return _defaultProtocols; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java index 78f6d38d93..f3ddf32e5a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/QueueAdapter.java @@ -43,6 +43,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.queue.*; import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.util.MapValueConverter; final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.SubscriptionRegistrationListener, AMQQueue.NotificationListener { @@ -50,15 +51,16 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs static final Map<String, String> ATTRIBUTE_MAPPINGS = new HashMap<String, String>(); static { - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_REPEAT_GAP, "x-qpid-minimum-alert-repeat-gap"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, "x-qpid-maximum-message-age"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, "x-qpid-maximum-message-size"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, "x-qpid-maximum-message-count"); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_REPEAT_GAP, AMQQueueFactory.X_QPID_MINIMUM_ALERT_REPEAT_GAP); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_AGE); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_SIZE); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_COUNT); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_BYTES, AMQQueueFactory.X_QPID_MAXIMUM_QUEUE_DEPTH); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, "x-qpid-maximum-delivery-count"); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, AMQQueueFactory.X_QPID_MAXIMUM_DELIVERY_COUNT); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, "x-qpid-capacity"); - QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, "x-qpid-flow-resume-capacity"); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, AMQQueueFactory.X_QPID_CAPACITY); + QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, AMQQueueFactory.X_QPID_FLOW_RESUME_CAPACITY); QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.SORT_KEY, AMQQueueFactory.QPID_QUEUE_SORT_KEY); QueueAdapter.ATTRIBUTE_MAPPINGS.put(Queue.LVQ_KEY, AMQQueueFactory.QPID_LAST_VALUE_QUEUE_KEY); @@ -78,7 +80,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs public QueueAdapter(final VirtualHostAdapter virtualHostAdapter, final AMQQueue queue) { - super(queue.getId()); + super(queue.getId(), virtualHostAdapter.getTaskExecutor()); _vhost = virtualHostAdapter; addParent(org.apache.qpid.server.model.VirtualHost.class, virtualHostAdapter); @@ -205,47 +207,47 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs } @Override - public Object setAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException + public boolean changeAttribute(String name, Object expected, Object desired) throws IllegalStateException, AccessControlException, IllegalArgumentException { try { if(ALERT_REPEAT_GAP.equals(name)) { _queue.setMinimumAlertRepeatGap((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_MESSAGE_AGE.equals(name)) { _queue.setMaximumMessageAge((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_MESSAGE_SIZE.equals(name)) { _queue.setMaximumMessageSize((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_QUEUE_DEPTH_BYTES.equals(name)) { _queue.setMaximumQueueDepth((Long)desired); - return desired; + return true; } else if(ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES.equals(name)) { _queue.setMaximumMessageCount((Long)desired); - return desired; + return true; } else if(ALTERNATE_EXCHANGE.equals(name)) { // In future we may want to accept a UUID as an alternative way to identifying the exchange ExchangeAdapter alternateExchange = (ExchangeAdapter) desired; _queue.setAlternateExchange(alternateExchange == null ? null : alternateExchange.getExchange()); - return desired; + return true; } else if(EXCLUSIVE.equals(name)) { Boolean exclusiveFlag = (Boolean) desired; _queue.setExclusive(exclusiveFlag); - return desired; + return true; } else if(MESSAGE_GROUP_KEY.equals(name)) { @@ -266,7 +268,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs else if(MAXIMUM_DELIVERY_ATTEMPTS.equals(name)) { _queue.setMaximumDeliveryCount((Integer)desired); - return desired; + return true; } else if(NO_LOCAL.equals(name)) { @@ -279,12 +281,12 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs else if(QUEUE_FLOW_CONTROL_SIZE_BYTES.equals(name)) { _queue.setCapacity((Long)desired); - return desired; + return true; } else if(QUEUE_FLOW_RESUME_SIZE_BYTES.equals(name)) { _queue.setFlowResumeCapacity((Long)desired); - return desired; + return true; } else if(QUEUE_FLOW_STOPPED.equals(name)) { @@ -301,10 +303,10 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs else if (DESCRIPTION.equals(name)) { _queue.setDescription((String) desired); - return desired; + return true; } - return super.setAttribute(name, expected, desired); + return super.changeAttribute(name, expected, desired); } finally { @@ -495,8 +497,8 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs throws AccessControlException, IllegalStateException { attributes = new HashMap<String, Object>(attributes); - String bindingKey = getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); - Map<String, Object> bindingArgs = getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.EMPTY_MAP); + String bindingKey = MapValueConverter.getStringAttribute(org.apache.qpid.server.model.Binding.NAME, attributes, ""); + Map<String, Object> bindingArgs = MapValueConverter.getMapAttribute(org.apache.qpid.server.model.Binding.ARGUMENTS, attributes, Collections.<String,Object>emptyMap()); attributes.remove(org.apache.qpid.server.model.Binding.NAME); attributes.remove(org.apache.qpid.server.model.Binding.ARGUMENTS); @@ -508,7 +510,7 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == org.apache.qpid.server.model.Binding.class) { @@ -712,15 +714,15 @@ final class QueueAdapter extends AbstractAdapter implements Queue, AMQQueue.Subs } @Override - public State setDesiredState(State currentState, State desiredState) throws IllegalStateTransitionException, + protected boolean setState(State currentState, State desiredState) throws IllegalStateTransitionException, AccessControlException { if (desiredState == State.DELETED) { delete(); - return State.DELETED; + return true; } - return super.setDesiredState(currentState, desiredState); + return false; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java index d802697d67..2fffdb32f8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/SessionAdapter.java @@ -34,6 +34,7 @@ import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.Consumer; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.protocol.AMQSessionModel; final class SessionAdapter extends AbstractAdapter implements Session @@ -44,9 +45,9 @@ final class SessionAdapter extends AbstractAdapter implements Session private AMQSessionModel _session; private SessionStatistics _statistics; - public SessionAdapter(final AMQSessionModel session) + public SessionAdapter(final AMQSessionModel session, TaskExecutor taskExecutor) { - super(UUIDGenerator.generateRandomUUID()); + super(UUIDGenerator.generateRandomUUID(), taskExecutor); _session = session; _statistics = new SessionStatistics(); } @@ -141,13 +142,6 @@ final class SessionAdapter extends AbstractAdapter implements Session return super.getAttribute(name); //TODO - Implement } - @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } - public Statistics getStatistics() { return _statistics; @@ -237,4 +231,11 @@ final class SessionAdapter extends AbstractAdapter implements Session return null; // TODO - Implement } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO : add state management + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java new file mode 100644 index 0000000000..bdffe605ec --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java @@ -0,0 +1,43 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model.adapter; + +import java.util.Collection; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.TrustStore; + +public class TrustStoreAdapter extends AbstractKeyStoreAdapter implements TrustStore +{ + public TrustStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes) + { + super(id, broker, attributes); + } + + @Override + public Collection<String> getAttributeNames() + { + return AVAILABLE_ATTRIBUTES; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java index 35838e51d2..1d50be279f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAdapter.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.model.adapter; +import java.io.File; import java.security.AccessControlException; import java.security.Principal; import java.util.ArrayList; @@ -31,17 +32,27 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.SystemConfiguration; import org.apache.qpid.AMQException; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.configuration.XmlConfigurationUtilities.MyConfiguration; import org.apache.qpid.server.connection.IConnectionRegistry; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Connection; import org.apache.qpid.server.model.Exchange; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.QueueType; import org.apache.qpid.server.model.State; @@ -49,22 +60,38 @@ import org.apache.qpid.server.model.Statistics; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.txn.LocalTransaction; import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.util.MapValueConverter; +import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener, +public final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, ExchangeRegistry.RegistryChangeListener, QueueRegistry.RegistryChangeListener, IConnectionRegistry.RegistryChangeListener { - private final org.apache.qpid.server.virtualhost.VirtualHost _virtualHost; + @SuppressWarnings("serial") + public static final Map<String, Class<?>> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Class<?>>(){{ + put(NAME, String.class); + put(STORE_PATH, String.class); + put(STORE_TYPE, String.class); + put(CONFIG_PATH, String.class); + put(STATE, State.class); + }}); + + private org.apache.qpid.server.virtualhost.VirtualHost _virtualHost; private final Map<AMQConnectionModel, ConnectionAdapter> _connectionAdapters = new HashMap<AMQConnectionModel, ConnectionAdapter>(); @@ -74,37 +101,52 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E private final Map<org.apache.qpid.server.exchange.Exchange, ExchangeAdapter> _exchangeAdapters = new HashMap<org.apache.qpid.server.exchange.Exchange, ExchangeAdapter>(); - - private final StatisticsAdapter _statistics; - - private final BrokerAdapter _broker; - + private StatisticsAdapter _statistics; + private final Broker _broker; private final List<VirtualHostAlias> _aliases = new ArrayList<VirtualHostAlias>(); + private StatisticsGatherer _brokerStatisticsGatherer; - - VirtualHostAdapter(BrokerAdapter brokerAdapter, - final org.apache.qpid.server.virtualhost.VirtualHost virtualHost) + public VirtualHostAdapter(UUID id, Map<String, Object> attributes, Broker broker, StatisticsGatherer brokerStatisticsGatherer, TaskExecutor taskExecutor) { - super(virtualHost.getId()); - _broker = brokerAdapter; - _virtualHost = virtualHost; - _statistics = new VirtualHostStatisticsAdapter(virtualHost); - virtualHost.getQueueRegistry().addRegistryChangeListener(this); - populateQueues(); - virtualHost.getExchangeRegistry().addRegistryChangeListener(this); - populateExchanges(); - virtualHost.getConnectionRegistry().addRegistryChangeListener(this); - populateConnections(); - + super(id, null, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); + validateAttributes(); + _broker = broker; + _brokerStatisticsGatherer = brokerStatisticsGatherer; + addParent(Broker.class, broker); + } + private void validateAttributes() + { + String name = getName(); + if (name == null || "".equals(name.trim())) + { + throw new IllegalConfigurationException("Virtual host name must be specified"); + } - for(Port port :_broker.getPorts()) + String configurationFile = (String) getAttribute(CONFIG_PATH); + String storePath = (String) getAttribute(STORE_PATH); + String storeType = (String) getAttribute(STORE_TYPE); + boolean invalidAttributes = false; + if (configurationFile == null) + { + if (storePath == null || storeType == null) + { + invalidAttributes = true; + } + } + else + { + if (storePath != null || storeType != null) + { + invalidAttributes = true; + } + } + if (invalidAttributes) { - _aliases.add(new VirtualHostAliasAdapter(this, port)); + throw new IllegalConfigurationException("Please specify either the 'configPath' attribute or both 'storePath' and 'storeType' attributes"); } } - private void populateExchanges() { Collection<org.apache.qpid.server.exchange.Exchange> actualExchanges = @@ -126,37 +168,22 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E private void populateQueues() { Collection<AMQQueue> actualQueues = _virtualHost.getQueueRegistry().getQueues(); - - synchronized(_queueAdapters) - { - for(AMQQueue queue : actualQueues) - { - if(!_queueAdapters.containsKey(queue)) - { - _queueAdapters.put(queue, new QueueAdapter(this,queue)); - } - } - } - } - - private void populateConnections() - { - - List<AMQConnectionModel> actualConnections = _virtualHost.getConnectionRegistry().getConnections(); - - synchronized(_connectionAdapters) + if ( actualQueues != null ) { - for(AMQConnectionModel conn : actualConnections) + synchronized(_queueAdapters) { - if(!_connectionAdapters.containsKey(conn)) + for(AMQQueue queue : actualQueues) { - _connectionAdapters.put(conn, new ConnectionAdapter(conn)); + if(!_queueAdapters.containsKey(queue)) + { + _queueAdapters.put(queue, new QueueAdapter(this, queue)); + } } } } - } + @Override public String getReplicationGroupName() { return null; //TODO @@ -198,12 +225,12 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { attributes = new HashMap<String, Object>(attributes); - String name = getStringAttribute(Exchange.NAME, attributes, null); - State state = getEnumAttribute(State.class, Exchange.STATE, attributes, State.ACTIVE); - boolean durable = getBooleanAttribute(Exchange.DURABLE, attributes, false); - LifetimePolicy lifetime = getEnumAttribute(LifetimePolicy.class, Exchange.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); - String type = getStringAttribute(Exchange.TYPE, attributes, null); - long ttl = getLongAttribute(Exchange.TIME_TO_LIVE, attributes, 0l); + String name = MapValueConverter.getStringAttribute(Exchange.NAME, attributes, null); + State state = MapValueConverter.getEnumAttribute(State.class, Exchange.STATE, attributes, State.ACTIVE); + boolean durable = MapValueConverter.getBooleanAttribute(Exchange.DURABLE, attributes, false); + LifetimePolicy lifetime = MapValueConverter.getEnumAttribute(LifetimePolicy.class, Exchange.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); + String type = MapValueConverter.getStringAttribute(Exchange.TYPE, attributes, null); + long ttl = MapValueConverter.getLongAttribute(Exchange.TIME_TO_LIVE, attributes, 0l); attributes.remove(Exchange.NAME); attributes.remove(Exchange.STATE); @@ -266,7 +293,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E if (attributes.containsKey(Queue.TYPE)) { - String typeAttribute = getStringAttribute(Queue.TYPE, attributes, null); + String typeAttribute = MapValueConverter.getStringAttribute(Queue.TYPE, attributes, null); QueueType queueType = null; try { @@ -289,12 +316,12 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E throw new IllegalArgumentException("Sort key is not specified for sorted queue"); } } - String name = getStringAttribute(Queue.NAME, attributes, null); - State state = getEnumAttribute(State.class, Queue.STATE, attributes, State.ACTIVE); - boolean durable = getBooleanAttribute(Queue.DURABLE, attributes, false); - LifetimePolicy lifetime = getEnumAttribute(LifetimePolicy.class, Queue.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); - long ttl = getLongAttribute(Queue.TIME_TO_LIVE, attributes, 0l); - boolean exclusive= getBooleanAttribute(Queue.EXCLUSIVE, attributes, false); + String name = MapValueConverter.getStringAttribute(Queue.NAME, attributes, null); + State state = MapValueConverter.getEnumAttribute(State.class, Queue.STATE, attributes, State.ACTIVE); + boolean durable = MapValueConverter.getBooleanAttribute(Queue.DURABLE, attributes, false); + LifetimePolicy lifetime = MapValueConverter.getEnumAttribute(LifetimePolicy.class, Queue.LIFETIME_POLICY, attributes, LifetimePolicy.PERMANENT); + long ttl = MapValueConverter.getLongAttribute(Queue.TIME_TO_LIVE, attributes, 0l); + boolean exclusive= MapValueConverter.getBooleanAttribute(Queue.EXCLUSIVE, attributes, false); attributes.remove(Queue.NAME); attributes.remove(Queue.STATE); @@ -328,11 +355,10 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E String owner = null; if(exclusive) { - Set<Principal> principals = - SecurityManager.getThreadSubject().getPrincipals(); - if(principals != null && !principals.isEmpty()) + Principal authenticatedPrincipal = AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(SecurityManager.getThreadSubject()); + if(authenticatedPrincipal != null) { - owner = principals.iterator().next().getName(); + owner = authenticatedPrincipal.getName(); } } try @@ -370,7 +396,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E public String getName() { - return _virtualHost.getName(); + return (String)getAttribute(NAME); } public String setName(final String currentName, final String desiredName) @@ -379,9 +405,36 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E throw new IllegalStateException(); } + @Override public State getActualState() { - return getDesiredState(); + if (_virtualHost == null) + { + State state = (State)super.getAttribute(STATE); + if (state == null) + { + return State.INITIALISING; + } + return state; + } + else + { + org.apache.qpid.server.virtualhost.State implementationState = _virtualHost.getState(); + switch(implementationState) + { + case INITIALISING: + return State.INITIALISING; + case ACTIVE: + return State.ACTIVE; + case PASSIVE: + return State.QUIESCED; + case STOPPED: + return State.STOPPED; + default: + // unexpected state + return null; + } + } } public boolean isDurable() @@ -448,7 +501,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E } @Override - public <C extends ConfiguredObject> C createChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) + public <C extends ConfiguredObject> C addChild(Class<C> childClass, Map<String, Object> attributes, ConfiguredObject... otherParents) { if(childClass == Exchange.class) { @@ -548,7 +601,7 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { if(!_connectionAdapters.containsKey(connection)) { - adapter = new ConnectionAdapter(connection); + adapter = new ConnectionAdapter(connection, getTaskExecutor()); _connectionAdapters.put(connection, adapter); } @@ -709,13 +762,9 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { return getId(); } - else if(NAME.equals(name)) - { - return getName(); - } else if(STATE.equals(name)) { - return State.ACTIVE; + return getActualState(); } else if(DURABLE.equals(name)) { @@ -737,10 +786,19 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { // TODO } - else if(SUPPORTED_EXCHANGE_TYPES.equals(name)) + else if (_virtualHost != null) + { + return getAttributeFromVirtualHostImplementation(name); + } + return super.getAttribute(name); + } + + private Object getAttributeFromVirtualHostImplementation(String name) + { + if(SUPPORTED_EXCHANGE_TYPES.equals(name)) { List<String> types = new ArrayList<String>(); - for(ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes()) + for(@SuppressWarnings("rawtypes") ExchangeType type : _virtualHost.getExchangeFactory().getRegisteredTypes()) { types.add(type.getName().asString()); } @@ -754,10 +812,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { return _virtualHost.getConfiguration().isDeadLetterQueueEnabled(); } - else if(FEDERATION_TAG.equals(name)) - { - return _virtualHost.getFederationTag(); - } else if(HOUSEKEEPING_CHECK_PERIOD.equals(name)) { return _virtualHost.getConfiguration().getHousekeepingCheckPeriod(); @@ -778,9 +832,9 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E { return _virtualHost.getMessageStore().getStoreType(); } - else if(STORE_CONFIGURATION.equals(name)) + else if(STORE_PATH.equals(name)) { - // TODO + return _virtualHost.getMessageStore().getStoreLocation(); } else if(STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE.equals(name)) { @@ -822,13 +876,6 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E } @Override - public Object setAttribute(String name, Object expected, Object desired) - throws IllegalStateException, AccessControlException, IllegalArgumentException - { - return super.setAttribute(name, expected, desired); //TODO - Implement - } - - @Override public Collection<String> getAttributeNames() { return AVAILABLE_ATTRIBUTES; @@ -889,4 +936,111 @@ final class VirtualHostAdapter extends AbstractAdapter implements VirtualHost, E } } + + @Override + protected boolean setState(State currentState, State desiredState) + { + if (desiredState == State.ACTIVE) + { + activate(); + return true; + } + else if (desiredState == State.STOPPED) + { + if (_virtualHost != null) + { + try + { + _virtualHost.close(); + } + finally + { + _broker.getVirtualHostRegistry().unregisterVirtualHost(_virtualHost); + } + } + return true; + } + else if (desiredState == State.DELETED) + { + //TODO: add ACL check to authorize the operation + if (_virtualHost != null && _virtualHost.getState() == org.apache.qpid.server.virtualhost.State.ACTIVE) + { + setDesiredState(currentState, State.STOPPED); + } + return true; + } + return false; + } + + private void activate() + { + VirtualHostRegistry virtualHostRegistry = _broker.getVirtualHostRegistry(); + String virtualHostName = getName(); + try + { + VirtualHostConfiguration configuration = createVirtualHostConfiguration(virtualHostName); + _virtualHost = new VirtualHostImpl(_broker.getVirtualHostRegistry(), _brokerStatisticsGatherer, _broker.getSecurityManager(), configuration); + } + catch (Exception e) + { + throw new RuntimeException("Failed to create virtual host " + virtualHostName, e); + } + + virtualHostRegistry.registerVirtualHost(_virtualHost); + + _statistics = new VirtualHostStatisticsAdapter(_virtualHost); + _virtualHost.getQueueRegistry().addRegistryChangeListener(this); + populateQueues(); + _virtualHost.getExchangeRegistry().addRegistryChangeListener(this); + populateExchanges(); + _virtualHost.getConnectionRegistry().addRegistryChangeListener(this); + + synchronized(_aliases) + { + for(Port port :_broker.getPorts()) + { + if (Protocol.hasAmqpProtocol(port.getProtocols())) + { + _aliases.add(new VirtualHostAliasAdapter(this, port)); + } + } + } + } + + private VirtualHostConfiguration createVirtualHostConfiguration(String virtualHostName) throws ConfigurationException + { + VirtualHostConfiguration configuration; + String configurationFile = (String)getAttribute(CONFIG_PATH); + if (configurationFile == null) + { + final MyConfiguration basicConfiguration = new MyConfiguration(); + PropertiesConfiguration config = new PropertiesConfiguration(); + config.addProperty("store.type", (String)getAttribute(STORE_TYPE)); + config.addProperty("store.environment-path", (String)getAttribute(STORE_PATH)); + basicConfiguration.addConfiguration(config); + + CompositeConfiguration compositeConfiguration = new CompositeConfiguration(); + compositeConfiguration.addConfiguration(new SystemConfiguration()); + compositeConfiguration.addConfiguration(basicConfiguration); + configuration = new VirtualHostConfiguration(virtualHostName, compositeConfiguration , _broker); + } + else + { + configuration = new VirtualHostConfiguration(virtualHostName, new File(configurationFile) , _broker); + } + return configuration; + } + + @Override + public SecurityManager getSecurityManager() + { + return _virtualHost.getSecurityManager(); + } + + @Override + public MessageStore getMessageStore() + { + return _virtualHost.getMessageStore(); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java index 367d1ff518..91b705b004 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/model/adapter/VirtualHostAliasAdapter.java @@ -43,7 +43,7 @@ public class VirtualHostAliasAdapter extends AbstractAdapter implements Virtual public VirtualHostAliasAdapter(VirtualHostAdapter virtualHostAdapter, Port port) { - super(UUIDGenerator.generateVhostAliasUUID(virtualHostAdapter.getName(), port.getName())); + super(UUIDGenerator.generateVhostAliasUUID(virtualHostAdapter.getName(), port.getName()), virtualHostAdapter.getTaskExecutor()); _vhost = virtualHostAdapter; _port = port; } @@ -140,4 +140,11 @@ public class VirtualHostAliasAdapter extends AbstractAdapter implements Virtual { throw new UnsupportedOperationException(); } + + @Override + protected boolean setState(State currentState, State desiredState) + { + // TODO: state is not supported at the moment + return false; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java index a68ac5439c..917215a42f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterImpl.java @@ -218,55 +218,71 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter final boolean isRedelivered = entry.isRedelivered(); - final AMQBody returnBlock = new AMQBody() - { - - private AMQBody _underlyingBody; - - public AMQBody createAMQBody() - { - return _methodRegistry.createBasicDeliverBody(consumerTag, - deliveryTag, - isRedelivered, - exchangeName, - routingKey); - - + final AMQBody returnBlock = new EncodedDeliveryBody(deliveryTag, routingKey, exchangeName, consumerTag, isRedelivered); + return returnBlock; + } + private class EncodedDeliveryBody implements AMQBody + { + private final long _deliveryTag; + private final AMQShortString _routingKey; + private final AMQShortString _exchangeName; + private final AMQShortString _consumerTag; + private final boolean _isRedelivered; + private AMQBody _underlyingBody; + + private EncodedDeliveryBody(long deliveryTag, AMQShortString routingKey, AMQShortString exchangeName, AMQShortString consumerTag, boolean isRedelivered) + { + _deliveryTag = deliveryTag; + _routingKey = routingKey; + _exchangeName = exchangeName; + _consumerTag = consumerTag; + _isRedelivered = isRedelivered; + } + public AMQBody createAMQBody() + { + return _methodRegistry.createBasicDeliverBody(_consumerTag, + _deliveryTag, + _isRedelivered, + _exchangeName, + _routingKey); + } - } + public byte getFrameType() + { + return AMQMethodBody.TYPE; + } - public byte getFrameType() + public int getSize() + { + if(_underlyingBody == null) { - return AMQMethodBody.TYPE; + _underlyingBody = createAMQBody(); } + return _underlyingBody.getSize(); + } - public int getSize() + public void writePayload(DataOutput buffer) throws IOException + { + if(_underlyingBody == null) { - if(_underlyingBody == null) - { - _underlyingBody = createAMQBody(); - } - return _underlyingBody.getSize(); + _underlyingBody = createAMQBody(); } + _underlyingBody.writePayload(buffer); + } - public void writePayload(DataOutput buffer) throws IOException - { - if(_underlyingBody == null) - { - _underlyingBody = createAMQBody(); - } - _underlyingBody.writePayload(buffer); - } + public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession) + throws AMQException + { + throw new AMQException("This block should never be dispatched!"); + } - public void handle(final int channelId, final AMQVersionAwareProtocolSession amqMinaProtocolSession) - throws AMQException - { - throw new AMQException("This block should never be dispatched!"); - } - }; - return returnBlock; + @Override + public String toString() + { + return "[" + getClass().getSimpleName() + " underlyingBody: " + String.valueOf(_underlyingBody) + "]"; + } } private AMQBody createEncodedGetOkBody(QueueEntry entry, long deliveryTag, int queueSize) @@ -368,7 +384,6 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter _methodBody = methodBody; _headerBody = headerBody; _contentBody = contentBody; - } public long getSize() @@ -380,6 +395,19 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter { AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody, _contentBody); } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append("[").append(getClass().getSimpleName()) + .append(" methodBody=").append(_methodBody) + .append(", headerBody=").append(_headerBody) + .append(", contentBody=").append(_contentBody) + .append(", channel=").append(_channel).append("]"); + return builder.toString(); + } + } public static final class SmallCompositeAMQBodyBlock extends AMQDataBlock @@ -408,6 +436,17 @@ class ProtocolOutputConverterImpl implements ProtocolOutputConverter { AMQFrame.writeFrames(buffer, _channel, _methodBody, _headerBody); } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName()) + .append("methodBody=").append(_methodBody) + .append(", headerBody=").append(_headerBody) + .append(", channel=").append(_channel).append("]"); + return builder.toString(); + } } }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java new file mode 100644 index 0000000000..7708b90efc --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/AccessControlFactory.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.Map; + +import org.apache.qpid.server.security.AccessControl; + +public interface AccessControlFactory +{ + AccessControl createInstance(Map<String, Object> attributes); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java new file mode 100644 index 0000000000..95e6b4feb0 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.Map; + +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; + + +public interface AuthenticationManagerFactory +{ + public static final String ATTRIBUTE_TYPE = "authenticationProviderType"; + + AuthenticationManager createInstance(Map<String, Object> attributes); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java index a01e41f039..40ef6ad6a2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/ExchangeType.java @@ -18,19 +18,18 @@ * under the License. * */ -package org.apache.qpid.server.exchange; +package org.apache.qpid.server.plugin; import java.util.UUID; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.virtualhost.VirtualHost; - public interface ExchangeType<T extends Exchange> { public AMQShortString getName(); - public Class<T> getExchangeClass(); public T newInstance(UUID id, VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete) throws AMQException; public AMQShortString getDefaultExchangeName(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java new file mode 100644 index 0000000000..5d80ca24fd --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/GroupManagerFactory.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.Map; + +import org.apache.qpid.server.security.group.GroupManager; + +public interface GroupManagerFactory +{ + GroupManager createInstance(Map<String, Object> attributes); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java new file mode 100644 index 0000000000..af24f62e28 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/PluginFactory.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.Plugin; + +public interface PluginFactory +{ + static final String PLUGIN_TYPE = "pluginType"; + + Plugin createInstance(UUID id, Map<String, Object> attributes, Broker broker); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java b/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java new file mode 100644 index 0000000000..a0e0346ce0 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/plugin/QpidServiceLoader.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.plugin; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ServiceLoader; + +import org.apache.log4j.Logger; + +/** + * Simple facade over a {@link ServiceLoader} to instantiate all configured implementations of an interface. + */ +public class QpidServiceLoader<C> +{ + private static final Logger _logger = Logger.getLogger(QpidServiceLoader.class); + + public Iterable<C> instancesOf(Class<C> clazz) + { + return instancesOf(clazz, false); + } + + /** + * @throws RuntimeException if at least one implementation is not found. + */ + public Iterable<C> atLeastOneInstanceOf(Class<C> clazz) + { + return instancesOf(clazz, true); + } + + private Iterable<C> instancesOf(Class<C> clazz, boolean atLeastOne) + { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Iterator<C> serviceLoaderIterator = ServiceLoader.load(clazz, classLoader).iterator(); + + // create a new list so we can log the count + List<C> serviceImplementations = new ArrayList<C>(); + while(serviceLoaderIterator.hasNext()) + { + serviceImplementations.add(serviceLoaderIterator.next()); + } + + if(atLeastOne && serviceImplementations.isEmpty()) + { + throw new RuntimeException("At least one implementation of " + clazz + " expected"); + } + + if(_logger.isDebugEnabled()) + { + _logger.debug("Found " + serviceImplementations.size() + " implementations of " + clazz); + } + + return serviceImplementations; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java deleted file mode 100644 index 12e1eee9ca..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/Activator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.qpid.server.plugins; - -import org.apache.log4j.Logger; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.registry.ApplicationRegistry; - -public class Activator implements BundleActivator -{ - private static final Logger _logger = Logger.getLogger(Activator.class); - - private BundleContext _context = null; - - public void start(BundleContext ctx) throws Exception - { - _context = ctx; - _logger.info("Registering bundle: " + _context.getBundle().getSymbolicName()); - ctx.registerService(ServerConfiguration.class.getName(), ApplicationRegistry.getInstance().getConfiguration(), null); - } - - public void stop(BundleContext ctx) throws Exception - { - _logger.info("Stopping bundle: " + _context.getBundle().getSymbolicName()); - _context = null; - } - - public BundleContext getContext() - { - return _context; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java deleted file mode 100644 index d2bb3e037c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackageUtil.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.qpid.server.plugins; - -import org.osgi.framework.Version; - -import java.util.Iterator; -import java.util.Map; - -/** - * Utility class to convert a map of package name to version numbers into the string - * with the format expected of a OSGi system package declaration: - * - * <code> - * org.xyz; version=1.0.0, org.xyz.xyz; version=1.0.0,... - * </code> - * - * Additionally, if the caller has provided a qpidPackageReleaseNumber and the package - * begins org.apache.qpid, this release number will be used, in preference to the one - * found in the Map. - * - * @see org.osgi.framework.Constants#FRAMEWORK_SYSTEMPACKAGES - * - */ -public class OsgiSystemPackageUtil -{ - private static final String APACHE_QPID_PKG_PREFIX = "org.apache.qpid"; - - private final Map<String, String> _packageNameVersionMap; - private final Version _qpidPackageReleaseNumber; - - public OsgiSystemPackageUtil(final Version qpidPackageReleaseNumber, final Map<String, String> packageNameVersionMap) - { - _qpidPackageReleaseNumber = qpidPackageReleaseNumber; - _packageNameVersionMap = packageNameVersionMap; - } - - public String getFormattedSystemPackageString() - { - if (_packageNameVersionMap == null || _packageNameVersionMap.size() == 0) - { - return null; - } - - final StringBuilder packages = new StringBuilder(); - - for(Iterator<String> itr = _packageNameVersionMap.keySet().iterator(); itr.hasNext();) - { - final String packageName = itr.next(); - final String packageVersion; - - if (_qpidPackageReleaseNumber != null && packageName.startsWith(APACHE_QPID_PKG_PREFIX)) - { - packageVersion = _qpidPackageReleaseNumber.toString(); - } - else - { - packageVersion = _packageNameVersionMap.get(packageName); - } - - packages.append(packageName); - packages.append("; "); - packages.append("version="); - packages.append(packageVersion); - - if (itr.hasNext()) - { - packages.append(", "); - } - } - - return packages.toString(); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties b/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties deleted file mode 100644 index 6479546355..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/OsgiSystemPackages.properties +++ /dev/null @@ -1,135 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one# -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -# -# OSGi framework system package list -# -# PluginManager uses these properties to construct the FRAMEWORK_SYSTEMPACKAGES list -# - -# Format is: -# <package>=<version> -# and PluginManager will convert this into: -# <package>; version=<version> -# e.g. org.osgi.framework; version=1.3.0 - -javax.management.openmbean=1.0.0 -javax.management=1.0.0 -javax.management.remote.rmi=1.0.0 -javax.management.remote=1.0.0 -javax.management.monitor=1.0.0 - -javax.crypto=1 -javax.crypto.spec=1 - -javax.servlet=2 -javax.servlet.http=2 - -javax.security.auth=1.0.0 -javax.security.auth.callback=1.0.0 -javax.security.auth.login=1.0.0 -javax.security.sasl=1.0.0 -javax.security=1.0.0 - -javax.rmi.ssl=1.0.0 - -org.xml.sax=1.0.0 -org.xml.sax.helpers=1.0.0 - -org.osgi.framework=1.3.0 -org.osgi.service.packageadmin=1.2.0 -org.osgi.service.startlevel=1.0.0 -org.osgi.service.url=1.0.0 -org.osgi.util.tracker=1.0.0 - -org.apache.commons.codec=1.3.0 -org.apache.commons.codec.binary=1.3.0 - -org.apache.commons.configuration=1.0.0 - -org.apache.commons.lang=1.0.0 -org.apache.commons.lang.builder=1.0.0 -org.apache.commons.lang.time=1.0.0 -org.apache.commons.logging=1.0.0 - -org.apache.log4j=1.2.16 - -org.slf4j=1.6.1 - -org.eclipse.jetty=7.6.3 -org.eclipse.jetty.http=7.6.3 -org.eclipse.jetty.io=7.6.3 -org.eclipse.jetty.io.nio=7.6.3 -org.eclipse.jetty.security=7.6.3 -org.eclipse.jetty.server=7.6.3 -org.eclipse.jetty.server.session=7.6.3 -org.eclipse.jetty.server.ssl=7.6.3 -org.eclipse.jetty.server.nio=7.6.3 -org.eclipse.jetty.servlet=7.6.3 -org.eclipse.jetty.util.ssl=7.6.3 - -org.codehaus.jackson=1.9.0 -org.codehaus.jackson.map=1.9.0 - -# For Qpid packages (org.apache.qpid), the version number is automatically overridden by QpidPropertis#getReleaseVersion() - -org.apache.qpid=0.0.0 -org.apache.qpid.common=0.0.0 -org.apache.qpid.exchange=0.0.0 -org.apache.qpid.framing=0.0.0 -org.apache.qpid.management.common.mbeans.annotations=0.0.0 -org.apache.qpid.management.common.mbeans=0.0.0 -org.apache.qpid.protocol=0.0.0 -org.apache.qpid.transport=0.0.0 -org.apache.qpid.transport.codec=0.0.0 -org.apache.qpid.server.binding=0.0.0 -org.apache.qpid.server.model=0.0.0 -org.apache.qpid.server.model.adapter=0.0.0 -org.apache.qpid.server.model.impl=0.0.0 -org.apache.qpid.server.configuration=0.0.0 -org.apache.qpid.server.configuration.plugins=0.0.0 -org.apache.qpid.server.configuration.management=0.0.0 -org.apache.qpid.server.connection=0.0.0 -org.apache.qpid.server.exchange=0.0.0 -org.apache.qpid.server.logging=0.0.0 -org.apache.qpid.server.logging.log4j=0.0.0 -org.apache.qpid.server.logging.actors=0.0.0 -org.apache.qpid.server.logging.messages=0.0.0 -org.apache.qpid.server.logging.subjects=0.0.0 -org.apache.qpid.server.message=0.0.0 -org.apache.qpid.server.persistent=0.0.0 -org.apache.qpid.server.plugins=0.0.0 -org.apache.qpid.server.protocol=0.0.0 -org.apache.qpid.server.queue=0.0.0 -org.apache.qpid.server.subscription=0.0.0 -org.apache.qpid.server.registry=0.0.0 -org.apache.qpid.server.security=0.0.0 -org.apache.qpid.server.security.access=0.0.0 -org.apache.qpid.server.security.access.plugins=0.0.0 -org.apache.qpid.server.security.auth=0.0.0 -org.apache.qpid.server.security.auth.sasl=0.0.0 -org.apache.qpid.server.security.auth.manager=0.0.0 -org.apache.qpid.server.security.auth.rmi=0.0.0 -org.apache.qpid.server.stats=0.0.0 -org.apache.qpid.server.virtualhost=0.0.0 -org.apache.qpid.server.virtualhost.plugins=0.0.0 -org.apache.qpid.util=0.0.0 - -org.apache.qpid.server.store.berkeleydb=0.0.0 - diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java deleted file mode 100644 index 6dcf688f2a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.qpid.server.plugins; - -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; - -public interface Plugin -{ - - /** - * Provide Configuration to this plugin - */ - public void configure(ConfigurationPlugin config) throws ConfigurationException; -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java deleted file mode 100644 index 7ea2b95b89..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.qpid.server.plugins; - -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; - -public interface PluginFactory<P extends Plugin> -{ - public Class<P> getPluginClass(); - - public String getPluginName(); - - public P newInstance(ConfigurationPlugin config) throws ConfigurationException; -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java deleted file mode 100644 index 74abbccd2b..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.qpid.server.plugins; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.felix.framework.Felix; -import org.apache.felix.framework.util.StringMap; -import org.apache.log4j.Logger; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.server.configuration.TopicConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration.SlowConsumerDetectionConfigurationFactory; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionPolicyConfiguration.SlowConsumerDetectionPolicyConfigurationFactory; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration.SlowConsumerDetectionQueueConfigurationFactory; -import org.apache.qpid.server.exchange.ExchangeType; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.SecurityPluginFactory; -import org.apache.qpid.server.security.access.plugins.LegacyAccess; -import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory; -import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManager; -import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection; -import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory; -import org.apache.qpid.server.virtualhost.plugins.policies.TopicDeletePolicy; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory; -import org.apache.qpid.util.FileUtils; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleException; -import org.osgi.framework.Version; -import org.osgi.framework.launch.Framework; -import org.osgi.util.tracker.ServiceTracker; - -import static org.apache.felix.framework.util.FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_DIR_PROPERY; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE; -import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_START_VALUE; -import static org.apache.felix.main.AutoProcessor.process; -import static org.osgi.framework.Constants.FRAMEWORK_STORAGE; -import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN; -import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT; -import static org.osgi.framework.Constants.FRAMEWORK_SYSTEMPACKAGES; - -/** - * Provides access to pluggable elements, such as exchanges - */ -@SuppressWarnings("unchecked") -public class PluginManager implements Closeable -{ - private static final Logger _logger = Logger.getLogger(PluginManager.class); - - private static final int FELIX_STOP_TIMEOUT = 30000; - - private Framework _felix; - - private ServiceTracker _exchangeTracker = null; - private ServiceTracker _securityTracker = null; - private ServiceTracker _configTracker = null; - private ServiceTracker _virtualHostTracker = null; - private ServiceTracker _policyTracker = null; - private ServiceTracker _authenticationManagerTracker = null; - - private Activator _activator; - - private final List<ServiceTracker> _trackers = new ArrayList<ServiceTracker>(); - private Map<String, SecurityPluginFactory> _securityPlugins = new HashMap<String, SecurityPluginFactory>(); - private Map<List<String>, ConfigurationPluginFactory> _configPlugins = new IdentityHashMap<List<String>, ConfigurationPluginFactory>(); - private Map<String, VirtualHostPluginFactory> _vhostPlugins = new HashMap<String, VirtualHostPluginFactory>(); - private Map<String, SlowConsumerPolicyPluginFactory> _policyPlugins = new HashMap<String, SlowConsumerPolicyPluginFactory>(); - private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> _authenticationManagerPlugins = new HashMap<String, AuthenticationManagerPluginFactory<? extends Plugin>>(); - - /** The default name of the OSGI system package list. */ - private static final String DEFAULT_RESOURCE_NAME = "org/apache/qpid/server/plugins/OsgiSystemPackages.properties"; - - /** The name of the override system property that holds the name of the OSGI system package list. */ - private static final String FILE_PROPERTY = "qpid.osgisystempackages.properties"; - - private static final String OSGI_SYSTEM_PACKAGES; - - static - { - final String filename = System.getProperty(FILE_PROPERTY); - final InputStream is = FileUtils.openFileOrDefaultResource(filename, DEFAULT_RESOURCE_NAME, - PluginManager.class.getClassLoader()); - - try - { - Version qpidReleaseVersion; - try - { - qpidReleaseVersion = Version.parseVersion(QpidProperties.getReleaseVersion()); - } - catch (IllegalArgumentException iae) - { - qpidReleaseVersion = null; - } - - final Properties p = new Properties(); - p.load(is); - - final OsgiSystemPackageUtil osgiSystemPackageUtil = new OsgiSystemPackageUtil(qpidReleaseVersion, (Map)p); - - OSGI_SYSTEM_PACKAGES = osgiSystemPackageUtil.getFormattedSystemPackageString(); - - _logger.debug("List of OSGi system packages to be added: " + OSGI_SYSTEM_PACKAGES); - } - catch (IOException e) - { - _logger.error("Error reading OSGI system package list", e); - throw new ExceptionInInitializerError(e); - } - } - - - public PluginManager(String pluginPath, String cachePath, BundleContext bundleContext) throws Exception - { - // Store all non-OSGi plugins - // A little gross that we have to add them here, but not all the plugins are OSGIfied - for (SecurityPluginFactory<?> pluginFactory : Arrays.asList(LegacyAccess.FACTORY)) - { - _securityPlugins.put(pluginFactory.getPluginName(), pluginFactory); - } - for (ConfigurationPluginFactory configFactory : Arrays.asList( - TopicConfiguration.FACTORY, - SecurityManager.SecurityConfiguration.FACTORY, - LegacyAccess.LegacyAccessConfiguration.FACTORY, - new SlowConsumerDetectionConfigurationFactory(), - new SlowConsumerDetectionPolicyConfigurationFactory(), - new SlowConsumerDetectionQueueConfigurationFactory(), - PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY, - AnonymousAuthenticationManager.AnonymousAuthenticationManagerConfiguration.FACTORY, - KerberosAuthenticationManager.KerberosAuthenticationManagerConfiguration.FACTORY, - SimpleLDAPAuthenticationManager.SimpleLDAPAuthenticationManagerConfiguration.FACTORY, - ExternalAuthenticationManager.ExternalAuthenticationManagerConfiguration.FACTORY - )) - { - _configPlugins.put(configFactory.getParentPaths(), configFactory); - } - for (SlowConsumerPolicyPluginFactory pluginFactory : Arrays.asList( - new TopicDeletePolicy.TopicDeletePolicyFactory())) - { - _policyPlugins.put(pluginFactory.getPluginName(), pluginFactory); - } - for (VirtualHostPluginFactory pluginFactory : Arrays.asList( - new SlowConsumerDetection.SlowConsumerFactory())) - { - _vhostPlugins.put(pluginFactory.getClass().getName(), pluginFactory); - } - - for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList( - PrincipalDatabaseAuthenticationManager.FACTORY, AnonymousAuthenticationManager.FACTORY, - KerberosAuthenticationManager.FACTORY, SimpleLDAPAuthenticationManager.FACTORY, - ExternalAuthenticationManager.FACTORY)) - { - _authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory); - } - - if(bundleContext == null) - { - // Check the plugin directory path is set and exist - if (pluginPath == null) - { - _logger.info("No plugin path specified, no plugins will be loaded."); - return; - } - File pluginDir = new File(pluginPath); - if (!pluginDir.exists()) - { - _logger.warn("Plugin dir : " + pluginDir + " does not exist."); - return; - } - - // Add the bundle provided service interface package and the core OSGi - // packages to be exported from the class path via the system bundle. - - // Setup OSGi configuration property map - final StringMap configMap = new StringMap(false); - configMap.put(FRAMEWORK_SYSTEMPACKAGES, OSGI_SYSTEM_PACKAGES); - - // No automatic shutdown hook - configMap.put("felix.shutdown.hook", "false"); - - // Add system activator - List<BundleActivator> activators = new ArrayList<BundleActivator>(); - _activator = new Activator(); - activators.add(_activator); - configMap.put(SYSTEMBUNDLE_ACTIVATORS_PROP, activators); - - if (cachePath != null) - { - File cacheDir = new File(cachePath); - if (!cacheDir.exists() && cacheDir.canWrite()) - { - _logger.info("Creating plugin cache directory: " + cachePath); - cacheDir.mkdir(); - } - - // Set plugin cache directory and empty it - _logger.info("Cache bundles in directory " + cachePath); - configMap.put(FRAMEWORK_STORAGE, cachePath); - } - configMap.put(FRAMEWORK_STORAGE_CLEAN, FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); - - // Set directory with plugins to auto-deploy - _logger.info("Auto deploying bundles from directory " + pluginPath); - configMap.put(AUTO_DEPLOY_DIR_PROPERY, pluginPath); - configMap.put(AUTO_DEPLOY_ACTION_PROPERY, AUTO_DEPLOY_INSTALL_VALUE + "," + AUTO_DEPLOY_START_VALUE); - - // Start plugin manager - _felix = new Felix(configMap); - try - { - _logger.info("Starting plugin manager framework"); - _felix.init(); - process(configMap, _felix.getBundleContext()); - _felix.start(); - _logger.info("Started plugin manager framework"); - } - catch (BundleException e) - { - throw new ConfigurationException("Could not start plugin manager: " + e.getMessage(), e); - } - - bundleContext = _activator.getContext(); - } - else - { - _logger.info("Using the specified external BundleContext"); - } - - _exchangeTracker = new ServiceTracker(bundleContext, ExchangeType.class.getName(), null); - _exchangeTracker.open(); - _trackers.add(_exchangeTracker); - - _securityTracker = new ServiceTracker(bundleContext, SecurityPluginFactory.class.getName(), null); - _securityTracker.open(); - _trackers.add(_securityTracker); - - _configTracker = new ServiceTracker(bundleContext, ConfigurationPluginFactory.class.getName(), null); - _configTracker.open(); - _trackers.add(_configTracker); - - _virtualHostTracker = new ServiceTracker(bundleContext, VirtualHostPluginFactory.class.getName(), null); - _virtualHostTracker.open(); - _trackers.add(_virtualHostTracker); - - _policyTracker = new ServiceTracker(bundleContext, SlowConsumerPolicyPluginFactory.class.getName(), null); - _policyTracker.open(); - _trackers.add(_policyTracker); - - _authenticationManagerTracker = new ServiceTracker(bundleContext, AuthenticationManagerPluginFactory.class.getName(), null); - _authenticationManagerTracker.open(); - _trackers.add(_authenticationManagerTracker); - - _logger.info("Opened service trackers"); - } - - private static <T> Map<String, T> getServices(ServiceTracker tracker) - { - Map<String, T> services = new HashMap<String, T>(); - - if ((tracker != null) && (tracker.getServices() != null)) - { - for (Object service : tracker.getServices()) - { - if (service instanceof PluginFactory<?>) - { - services.put(((PluginFactory<?>) service).getPluginName(), (T) service); - } - else - { - services.put(service.getClass().getName(), (T) service); - } - } - } - - return services; - } - - public static <T> Map<String, T> getServices(ServiceTracker tracker, Map<String, T> plugins) - { - Map<String, T> services = getServices(tracker); - services.putAll(plugins); - return services; - } - - public Map<List<String>, ConfigurationPluginFactory> getConfigurationPlugins() - { - Map<List<String>, ConfigurationPluginFactory> services = new IdentityHashMap<List<String>, ConfigurationPluginFactory>(); - - if (_configTracker != null && _configTracker.getServices() != null) - { - for (Object service : _configTracker.getServices()) - { - ConfigurationPluginFactory factory = (ConfigurationPluginFactory) service; - services.put(factory.getParentPaths(), factory); - } - } - - services.putAll(_configPlugins); - - return services; - } - - public Map<String, VirtualHostPluginFactory> getVirtualHostPlugins() - { - return getServices(_virtualHostTracker, _vhostPlugins); - } - - public Map<String, SlowConsumerPolicyPluginFactory> getSlowConsumerPlugins() - { - return getServices(_policyTracker, _policyPlugins); - } - - public Map<String, ExchangeType<?>> getExchanges() - { - return getServices(_exchangeTracker); - } - - public Map<String, SecurityPluginFactory> getSecurityPlugins() - { - return getServices(_securityTracker, _securityPlugins); - } - - public Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> getAuthenticationManagerPlugins() - { - return getServices(_authenticationManagerTracker, _authenticationManagerPlugins); - } - - public void close() - { - try - { - // Close all bundle trackers - for(ServiceTracker tracker : _trackers) - { - tracker.close(); - } - } - finally - { - if (_felix != null) - { - _logger.info("Stopping plugin manager framework"); - try - { - // FIXME should be stopAndWait() but hangs VM, need upgrade in felix - _felix.stop(); - } - catch (BundleException e) - { - // Ignore - } - - try - { - _felix.waitForStop(FELIX_STOP_TIMEOUT); - } - catch (InterruptedException e) - { - // Ignore - } - _logger.info("Stopped plugin manager framework"); - } - else - { - _logger.info("Plugin manager was started with an external BundleContext, " + - "skipping remaining shutdown tasks"); - } - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java index 1e649c3cb7..ee1ef2418a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java @@ -29,11 +29,11 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -52,10 +52,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.protocol.ServerProtocolEngine; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.handler.ServerMethodDispatcherImpl; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; @@ -64,10 +61,11 @@ import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.ManagementActor; import org.apache.qpid.server.logging.messages.ConnectionMessages; import org.apache.qpid.server.logging.subjects.ConnectionLogSubject; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.output.ProtocolOutputConverterRegistry; import org.apache.qpid.server.queue.QueueEntry; -import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.stats.StatisticsCounter; @@ -75,13 +73,12 @@ import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionImpl; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.TransportException; import org.apache.qpid.transport.network.NetworkConnection; import org.apache.qpid.util.BytesDataOutput; -public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession, ConnectionConfig +public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSession { private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class); @@ -115,7 +112,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi private volatile boolean _closed; // maximum number of channels this session should have - private long _maxNoOfChannels = ApplicationRegistry.getInstance().getConfiguration().getMaxChannelCount(); + private long _maxNoOfChannels; /* AMQP Version for this session */ private ProtocolVersion _protocolVersion = ProtocolVersion.getLatestSupportedVersion(); @@ -142,8 +139,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi private long _maxFrameSize; private final AtomicBoolean _closing = new AtomicBoolean(false); - private final UUID _qmfId; - private final ConfigStore _configStore; private long _createTime = System.currentTimeMillis(); private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived; @@ -156,23 +151,25 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi private boolean _blocking; private final Lock _receivedLock; + private AtomicLong _lastWriteTime = new AtomicLong(System.currentTimeMillis()); + private final Broker _broker; - public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network, final long connectionId) + + public AMQProtocolEngine(Broker broker, NetworkConnection network, final long connectionId) { + _broker = broker; + _maxNoOfChannels = (Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT); _receivedLock = new ReentrantLock(); - _stateManager = new AMQStateManager(virtualHostRegistry, this); + _stateManager = new AMQStateManager(broker, this); _codecFactory = new AMQCodecFactory(true, this); setNetworkConnection(network); _connectionID = connectionId; - _actor = new AMQPConnectionActor(this, virtualHostRegistry.getApplicationRegistry().getRootMessageLogger()); + _actor = new AMQPConnectionActor(this, _broker.getRootMessageLogger()); _logSubject = new ConnectionLogSubject(this); - _configStore = virtualHostRegistry.getConfigStore(); - _qmfId = _configStore.createId(); - _actor.message(ConnectionMessages.OPEN(null, null, null, false, false, false)); initialiseStatistics(); @@ -309,9 +306,13 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi try { + long startTime = 0; + String frameToString = null; if (_logger.isDebugEnabled()) { - _logger.debug("Frame Received: " + frame); + startTime = System.currentTimeMillis(); + frameToString = frame.toString(); + _logger.debug("RECV: " + frame); } // Check that this channel is not closing @@ -346,6 +347,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi closeChannel(channelId); throw e; } + + if(_logger.isDebugEnabled()) + { + _logger.debug("Frame handled in " + (System.currentTimeMillis() - startTime) + " ms. Frame: " + frameToString); + } } finally { @@ -367,7 +373,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi // This sets the protocol version (and hence framing classes) for this session. setProtocolVersion(pv); - String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager(getLocalAddress()).getMechanisms(); + String mechanisms = _broker.getSubjectCreator(getLocalAddress()).getMechanisms(); String locales = "en_US"; @@ -549,8 +555,17 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi final ByteBuffer buf = asByteBuffer(frame); _writtenBytes += buf.remaining(); + + if(_logger.isDebugEnabled()) + { + _logger.debug("SEND: " + frame); + } + _sender.send(buf); - _lastIoTime = System.currentTimeMillis(); + final long time = System.currentTimeMillis(); + _lastIoTime = time; + _lastWriteTime.set(time); + if(!_deferFlush) { _sender.flush(); @@ -749,7 +764,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi if (delay > 0) { _network.setMaxWriteIdle(delay); - _network.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay)); + _network.setMaxReadIdle(BrokerProperties.DEFAULT_HEART_BEAT_TIMEOUT_FACTOR * delay); } } @@ -796,8 +811,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi closeAllChannels(); - getConfigStore().removeConfiguredObject(this); - for (Task task : _taskList) { task.doTask(this); @@ -983,7 +996,6 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi _virtualHost.getConnectionRegistry().registerConnection(this); - _configStore.addConfiguredObject(this); } public void addSessionCloseTask(Task task) @@ -1017,7 +1029,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi public Principal getAuthorizedPrincipal() { - return _authorizedSubject == null ? null : _authorizedSubject.getPrincipals().iterator().next(); + return _authorizedSubject == null ? null : AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(_authorizedSubject); } public SocketAddress getRemoteAddress() @@ -1070,12 +1082,12 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi public void readerIdle() { - // Nothing + // TODO - enforce disconnect on lack of inbound data } public synchronized void writerIdle() { - _sender.send(asByteBuffer(HeartbeatBody.FRAME)); + writeFrame(HeartbeatBody.FRAME); } public void exception(Throwable throwable) @@ -1185,32 +1197,11 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi return null; } - public ConfigStore getConfigStore() - { - return _configStore; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - public boolean isDurable() { return false; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - public long getConnectionId() { return getSessionID(); @@ -1494,4 +1485,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi { return _receivedLock; } + + @Override + public long getLastReadTime() + { + return _lastReceivedTime; + } + + @Override + public long getLastWriteTime() + { + return _lastWriteTime.get(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java index a8f62b0fa2..9d9bbe807b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java @@ -36,8 +36,7 @@ import org.apache.qpid.server.queue.SimpleAMQQueue; */ public interface AMQSessionModel extends Comparable<AMQSessionModel> { - /** Unique session ID across entire broker*/ - public UUID getQMFId(); + public UUID getId(); public AMQConnectionModel getConnectionModel(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java index 5c92aa95b6..d9e5e1c473 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java @@ -28,7 +28,7 @@ import java.util.Set; import org.apache.log4j.Logger; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.transport.ConnectionDelegate; import org.apache.qpid.transport.Sender; @@ -42,24 +42,24 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine private Set<AmqpProtocolVersion> _supported; private String _fqdn; - private IApplicationRegistry _appRegistry; + private final Broker _broker; private NetworkConnection _network; private Sender<ByteBuffer> _sender; private final AmqpProtocolVersion _defaultSupportedReply; private volatile ServerProtocolEngine _delegate = new SelfDelegateProtocolEngine(); - public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry, + public MultiVersionProtocolEngine(final Broker broker, final Set<AmqpProtocolVersion> supported, final AmqpProtocolVersion defaultSupportedReply, final long id, final NetworkConnection network) { - this(appRegistry, supported, defaultSupportedReply, id); + this(broker, supported, defaultSupportedReply, id); setNetworkConnection(network); } - public MultiVersionProtocolEngine(final IApplicationRegistry appRegistry, + public MultiVersionProtocolEngine(final Broker broker, final Set<AmqpProtocolVersion> supported, final AmqpProtocolVersion defaultSupportedReply, final long id) @@ -71,7 +71,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine } _id = id; - _appRegistry = appRegistry; + _broker = broker; _supported = supported; _defaultSupportedReply = defaultSupportedReply; } @@ -217,6 +217,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine _sender = sender; } + @Override + public long getLastReadTime() + { + return _delegate.getLastReadTime(); + } + + @Override + public long getLastWriteTime() + { + return _delegate.getLastWriteTime(); + } + private static interface DelegateCreator { @@ -240,7 +252,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id); + return new AMQProtocolEngine(_broker, _network, _id); } }; @@ -260,7 +272,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id); + return new AMQProtocolEngine(_broker, _network, _id); } }; @@ -280,7 +292,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network, _id); + return new AMQProtocolEngine(_broker, _network, _id); } }; @@ -301,13 +313,15 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - final ConnectionDelegate connDelegate = - new org.apache.qpid.server.transport.ServerConnectionDelegate(_appRegistry, _fqdn, _appRegistry.getAuthenticationManager(getLocalAddress())); + final ConnectionDelegate connDelegate = new org.apache.qpid.server.transport.ServerConnectionDelegate(_broker, + _fqdn, _broker.getSubjectCreator(getLocalAddress())); ServerConnection conn = new ServerConnection(_id); - conn.setConnectionDelegate(connDelegate); - return new ProtocolEngine_0_10( conn, _network, _appRegistry); + conn.setConnectionDelegate(connDelegate); + conn.setRemoteAddress(_network.getRemoteAddress()); + conn.setLocalAddress(_network.getLocalAddress()); + return new ProtocolEngine_0_10( conn, _network); } }; @@ -327,7 +341,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new ProtocolEngine_1_0_0(_appRegistry,_id); + return new ProtocolEngine_1_0_0(_network, _broker, _id); } }; @@ -347,7 +361,7 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public ServerProtocolEngine getProtocolEngine() { - return new ProtocolEngine_1_0_0_SASL(_network, _appRegistry, _id); + return new ProtocolEngine_1_0_0_SASL(_network, _broker, _id); } }; @@ -407,6 +421,18 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine } + @Override + public long getLastReadTime() + { + return 0; + } + + @Override + public long getLastWriteTime() + { + return 0; + } + public long getConnectionId() { return _id; @@ -547,7 +573,29 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine public void closed() { - + try + { + _delegate = new ClosedDelegateProtocolEngine(); + if(_logger.isDebugEnabled()) + { + _logger.debug("Connection from " + getRemoteAddress() + " was closed before any protocol version was established."); + } + } + catch(Exception e) + { + //ignore + } + finally + { + try + { + _network.close(); + } + catch(Exception e) + { + //ignore + } + } } public void writerIdle() @@ -564,5 +612,17 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine { } + + @Override + public long getLastReadTime() + { + return 0; + } + + @Override + public long getLastWriteTime() + { + return 0; + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java index 552b1c7054..9f078c8999 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java @@ -22,8 +22,7 @@ package org.apache.qpid.server.protocol; import org.apache.qpid.protocol.ProtocolEngineFactory; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.model.Broker; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -32,11 +31,12 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory { private static final AtomicLong ID_GENERATOR = new AtomicLong(0); - private final IApplicationRegistry _appRegistry; + private final Broker _broker; private final Set<AmqpProtocolVersion> _supported; private final AmqpProtocolVersion _defaultSupportedReply; - public MultiVersionProtocolEngineFactory(final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply) + public MultiVersionProtocolEngineFactory(Broker broker, + final Set<AmqpProtocolVersion> supportedVersions, final AmqpProtocolVersion defaultSupportedReply) { if(defaultSupportedReply != null && !supportedVersions.contains(defaultSupportedReply)) { @@ -44,14 +44,14 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory + ") to an unsupported protocol version initiation is itself not supported!"); } - _appRegistry = ApplicationRegistry.getInstance(); + _broker = broker; _supported = supportedVersions; _defaultSupportedReply = defaultSupportedReply; } public ServerProtocolEngine newProtocolEngine() { - return new MultiVersionProtocolEngine(_appRegistry, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement()); + return new MultiVersionProtocolEngine(_broker, _supported, _defaultSupportedReply, ID_GENERATOR.getAndIncrement()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java index fd6e9300ec..d5f7fe486c 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java @@ -21,13 +21,7 @@ package org.apache.qpid.server.protocol; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.ConnectionConfigType; -import org.apache.qpid.server.configuration.VirtualHostConfig; import org.apache.qpid.server.logging.messages.ConnectionMessages; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.Assembler; @@ -37,9 +31,9 @@ import org.apache.qpid.transport.network.NetworkConnection; import java.net.SocketAddress; import java.nio.ByteBuffer; -import java.util.UUID; -public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocolEngine, ConnectionConfig + +public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocolEngine { public static final int MAX_FRAME_SIZE = 64 * 1024 - 1; @@ -47,20 +41,17 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol private long _readBytes; private long _writtenBytes; private ServerConnection _connection; - private final UUID _qmfId; - private final IApplicationRegistry _appRegistry; + private long _createTime = System.currentTimeMillis(); + private long _lastReadTime; + private long _lastWriteTime; public ProtocolEngine_0_10(ServerConnection conn, - NetworkConnection network, - final IApplicationRegistry appRegistry) + NetworkConnection network) { super(new Assembler(conn)); _connection = conn; - _connection.setConnectionConfig(this); - _qmfId = appRegistry.getConfigStore().createId(); - _appRegistry = appRegistry; if(network != null) { @@ -68,14 +59,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol } - _connection.onOpen(new Runnable() - { - public void run() - { - getConfigStore().addConfiguredObject(ProtocolEngine_0_10.this); - } - }); - } public void setNetworkConnection(NetworkConnection network) @@ -87,13 +70,61 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol { _network = network; - _connection.setSender(new Disassembler(sender, MAX_FRAME_SIZE)); + _connection.setNetworkConnection(network); + _connection.setSender(new Disassembler(wrapSender(sender), MAX_FRAME_SIZE)); _connection.setPeerPrincipal(_network.getPeerPrincipal()); // FIXME Two log messages to maintain compatibility with earlier protocol versions _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, null, false, false, false)); _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", null, false, true, false)); } + private Sender<ByteBuffer> wrapSender(final Sender<ByteBuffer> sender) + { + return new Sender<ByteBuffer>() + { + @Override + public void setIdleTimeout(int i) + { + sender.setIdleTimeout(i); + + } + + @Override + public void send(ByteBuffer msg) + { + _lastWriteTime = System.currentTimeMillis(); + sender.send(msg); + + } + + @Override + public void flush() + { + sender.flush(); + + } + + @Override + public void close() + { + sender.close(); + + } + }; + } + + @Override + public long getLastReadTime() + { + return _lastReadTime; + } + + @Override + public long getLastWriteTime() + { + return _lastWriteTime; + } + public SocketAddress getRemoteAddress() { return _network.getRemoteAddress(); @@ -106,6 +137,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol public void received(final ByteBuffer buf) { + _lastReadTime = System.currentTimeMillis(); super.received(buf); _connection.receivedComplete(); } @@ -122,7 +154,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol public void writerIdle() { - //Todo + _connection.doHeartbeat(); } public void readerIdle() @@ -130,72 +162,16 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol //Todo } - public VirtualHostConfig getVirtualHost() - { - return _connection.getVirtualHost(); - } - public String getAddress() { return getRemoteAddress().toString(); } - public Boolean isIncoming() - { - return true; - } - - public Boolean isSystemConnection() - { - return false; - } - - public Boolean isFederationLink() - { - return false; - } - public String getAuthId() { return _connection.getAuthorizedPrincipal() == null ? null : _connection.getAuthorizedPrincipal().getName(); } - public String getRemoteProcessName() - { - return null; - } - - public Integer getRemotePID() - { - return null; - } - - public Integer getRemoteParentPID() - { - return null; - } - - public ConfigStore getConfigStore() - { - return _appRegistry.getConfigStore(); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - public boolean isDurable() { return false; @@ -205,7 +181,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol public void closed() { super.closed(); - getConfigStore().removeConfiguredObject(this); } public long getCreateTime() @@ -213,16 +188,6 @@ public class ProtocolEngine_0_10 extends InputHandler implements ServerProtocol return _createTime; } - public Boolean isShadow() - { - return false; - } - - public void mgmtClose() - { - _connection.mgmtClose(); - } - public long getConnectionId() { return _connection.getConnectionId(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java index e6282315c6..f6b8e1e5c9 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java @@ -22,7 +22,6 @@ package org.apache.qpid.server.protocol; import java.net.SocketAddress; import java.nio.ByteBuffer; -import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -39,11 +38,10 @@ import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler; import org.apache.qpid.amqp_1_0.type.Binary; import org.apache.qpid.amqp_1_0.type.FrameBody; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.v1_0.Connection_1_0; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.NetworkConnection; @@ -54,8 +52,9 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa //private NetworkConnection _networkDriver; private long _readBytes; private long _writtenBytes; - private final UUID _id; - private final IApplicationRegistry _appRegistry; + private long _lastReadTime; + private long _lastWriteTime; + private final Broker _broker; private long _createTime = System.currentTimeMillis(); private ConnectionEndpoint _conn; private final long _connectionId; @@ -99,11 +98,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa - public ProtocolEngine_1_0_0(final IApplicationRegistry appRegistry, long id) + public ProtocolEngine_1_0_0(final NetworkConnection networkDriver, final Broker broker, long id) { - _id = appRegistry.getConfigStore().createId(); - _appRegistry = appRegistry; + _broker = broker; _connectionId = id; + if(networkDriver != null) + { + setNetworkConnection(networkDriver, networkDriver.getSender()); + } } @@ -142,13 +144,15 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa _network = network; _sender = sender; - Container container = new Container(_appRegistry.getBrokerId().toString()); + Container container = new Container(_broker.getId().toString()); + + VirtualHost virtualHost = _broker.getVirtualHostRegistry().getVirtualHost((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)); - _conn = new ConnectionEndpoint(container, asSaslServerProvider(_appRegistry.getAuthenticationManager( + _conn = new ConnectionEndpoint(container, asSaslServerProvider(_broker.getSubjectCreator( getLocalAddress()))); - _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId)); - _conn.setFrameOutputHandler(this); _conn.setRemoteAddress(_network.getRemoteAddress()); + _conn.setConnectionEventListener(new Connection_1_0(virtualHost, _conn, _connectionId)); + _conn.setFrameOutputHandler(this); _frameWriter = new FrameWriter(_conn.getDescribedTypeRegistry()); _frameHandler = new FrameHandler(_conn); @@ -157,14 +161,14 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa _sender.flush(); } - private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager) + private SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator) { return new SaslServerProvider() { @Override public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException { - return authenticationManager.createSaslServer(mechanism, fqdn, null); + return subjectCreator.createSaslServer(mechanism, fqdn, null); } }; } @@ -174,22 +178,6 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa return getRemoteAddress().toString(); } - - public ConfigStore getConfigStore() - { - return _appRegistry.getConfigStore(); - } - - public UUID getId() - { - return _id; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - public boolean isDurable() { return false; @@ -197,6 +185,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa public synchronized void received(ByteBuffer msg) { + _lastReadTime = System.currentTimeMillis(); if(RAW_LOGGER.isLoggable(Level.FINE)) { ByteBuffer dup = msg.duplicate(); @@ -339,6 +328,7 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa synchronized(_sendLock) { + _lastWriteTime = System.currentTimeMillis(); if(FRAME_LOGGER.isLoggable(Level.FINE)) { FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody()); @@ -393,4 +383,13 @@ public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHa return _connectionId; } + public long getLastReadTime() + { + return _lastReadTime; + } + + public long getLastWriteTime() + { + return _lastWriteTime; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java index a48441bf30..3b02ef2e5b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java @@ -23,7 +23,6 @@ package org.apache.qpid.server.protocol; import java.io.PrintWriter; import java.net.SocketAddress; import java.nio.ByteBuffer; -import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import javax.security.sasl.SaslException; @@ -40,12 +39,10 @@ import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler; import org.apache.qpid.amqp_1_0.type.Binary; import org.apache.qpid.amqp_1_0.type.FrameBody; import org.apache.qpid.protocol.ServerProtocolEngine; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.v1_0.Connection_1_0; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Sender; import org.apache.qpid.transport.network.NetworkConnection; @@ -53,8 +50,10 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut { private long _readBytes; private long _writtenBytes; - private final UUID _id; - private final IApplicationRegistry _appRegistry; + + private long _lastReadTime; + private long _lastWriteTime; + private final Broker _broker; private long _createTime = System.currentTimeMillis(); private ConnectionEndpoint _conn; private long _connectionId; @@ -113,13 +112,11 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut private State _state = State.A; - public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final IApplicationRegistry appRegistry, + public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final Broker broker, long id) { - _id = appRegistry.getConfigStore().createId(); _connectionId = id; - _appRegistry = appRegistry; - + _broker = broker; if(networkDriver != null) { setNetworkConnection(networkDriver, networkDriver.getSender()); @@ -162,21 +159,17 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut _network = network; _sender = sender; - Container container = new Container(_appRegistry.getBrokerId().toString()); + Container container = new Container(_broker.getId().toString()); - _conn = new ConnectionEndpoint(container, asSaslServerProvider(ApplicationRegistry.getInstance() - .getAuthenticationManager(getLocalAddress()))); - _conn.setConnectionEventListener(new Connection_1_0(_appRegistry, _conn, _connectionId)); + VirtualHost virtualHost = _broker.getVirtualHostRegistry().getVirtualHost((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)); + _conn = new ConnectionEndpoint(container, asSaslServerProvider(_broker.getSubjectCreator(getLocalAddress()))); _conn.setRemoteAddress(getRemoteAddress()); - - + _conn.setConnectionEventListener(new Connection_1_0(virtualHost, _conn, _connectionId)); _conn.setFrameOutputHandler(this); _conn.setSaslFrameOutput(this); _conn.setOnSaslComplete(new Runnable() { - - public void run() { if(_conn.isAuthenticated()) @@ -201,14 +194,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut } - private SaslServerProvider asSaslServerProvider(final AuthenticationManager authenticationManager) + private SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator) { return new SaslServerProvider() { @Override public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException { - return authenticationManager.createSaslServer(mechanism, fqdn, null); + return subjectCreator.createSaslServer(mechanism, fqdn, null); } }; } @@ -218,22 +211,6 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut return getRemoteAddress().toString(); } - - public ConfigStore getConfigStore() - { - return _appRegistry.getConfigStore(); - } - - public UUID getId() - { - return _id; - } - - public ConnectionConfigType getConfigType() - { - return ConnectionConfigType.getInstance(); - } - public boolean isDurable() { return false; @@ -244,6 +221,7 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut public synchronized void received(ByteBuffer msg) { + _lastReadTime = System.currentTimeMillis(); if(RAW_LOGGER.isLoggable(Level.FINE)) { ByteBuffer dup = msg.duplicate(); @@ -386,17 +364,14 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut synchronized(_sendLock) { - + _lastWriteTime = System.currentTimeMillis(); if(FRAME_LOGGER.isLoggable(Level.FINE)) { FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody()); } - _frameWriter.setValue(amqFrame); - - ByteBuffer dup = ByteBuffer.allocate(_conn.getMaxFrameSize()); int size = _frameWriter.writeToBuffer(dup); @@ -447,4 +422,13 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut return _connectionId; } + public long getLastReadTime() + { + return _lastReadTime; + } + + public long getLastWriteTime() + { + return _lastWriteTime; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java index f429d8ba9f..cf4164c244 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java @@ -31,7 +31,6 @@ import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -44,7 +43,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTIO public class Connection_1_0 implements ConnectionEventListener { - private IApplicationRegistry _appRegistry; private VirtualHost _vhost; private final ConnectionEndpoint _conn; private final long _connectionId; @@ -62,10 +60,9 @@ public class Connection_1_0 implements ConnectionEventListener - public Connection_1_0(IApplicationRegistry appRegistry, ConnectionEndpoint conn, long connectionId) + public Connection_1_0(VirtualHost virtualHost, ConnectionEndpoint conn, long connectionId) { - _appRegistry = appRegistry; - _vhost = _appRegistry.getVirtualHostRegistry().getDefaultVirtualHost(); + _vhost = virtualHost; _conn = conn; _connectionId = connectionId; _vhost.getConnectionRegistry().registerConnection(_model); @@ -74,7 +71,7 @@ public class Connection_1_0 implements ConnectionEventListener public void remoteSessionCreation(SessionEndpoint endpoint) { - Session_1_0 session = new Session_1_0(_vhost, _appRegistry, this); + Session_1_0 session = new Session_1_0(_vhost, this); _sessions.add(session); endpoint.setSessionEventListener(session); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java index ba1a1ca45c..2cef27267b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java @@ -80,7 +80,7 @@ public class ExchangeDestination implements ReceivingDestination, SendingDestina { // NO-OP } - }, System.currentTimeMillis()); + }); return ACCEPTED; } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java index 140a815f57..fbce1666b7 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java @@ -23,9 +23,10 @@ package org.apache.qpid.server.protocol.v1_0; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.SessionConfig; import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.message.MessageMetaData_1_0; import org.apache.qpid.server.message.MessageReference; @@ -34,11 +35,45 @@ import org.apache.qpid.server.store.StoredMessage; public class Message_1_0 implements ServerMessage, InboundMessage { + + + private static final AtomicIntegerFieldUpdater<Message_1_0> _refCountUpdater = + AtomicIntegerFieldUpdater.newUpdater(Message_1_0.class, "_referenceCount"); + + private volatile int _referenceCount = 0; + private final StoredMessage<MessageMetaData_1_0> _storedMessage; private List<ByteBuffer> _fragments; private WeakReference<Session_1_0> _session; + public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage) + { + _storedMessage = storedMessage; + _session = null; + _fragments = restoreFragments(storedMessage); + } + + private static List<ByteBuffer> restoreFragments(StoredMessage<MessageMetaData_1_0> storedMessage) + { + ArrayList<ByteBuffer> fragments = new ArrayList<ByteBuffer>(); + final int FRAGMENT_SIZE = 2048; + int offset = 0; + ByteBuffer b; + do + { + + b = storedMessage.getContent(offset,FRAGMENT_SIZE); + if(b.hasRemaining()) + { + fragments.add(b); + offset+= b.remaining(); + } + } + while(b.hasRemaining()); + return fragments; + } + public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage, final List<ByteBuffer> fragments, final Session_1_0 session) @@ -136,11 +171,6 @@ public class Message_1_0 implements ServerMessage, InboundMessage return buf; } - public SessionConfig getSessionConfig() - { - return null; //TODO - } - public List<ByteBuffer> getFragments() { return _fragments; @@ -148,7 +178,61 @@ public class Message_1_0 implements ServerMessage, InboundMessage public Session_1_0 getSession() { - return _session.get(); + return _session == null ? null : _session.get(); + } + + + public boolean incrementReference() + { + if(_refCountUpdater.incrementAndGet(this) <= 0) + { + _refCountUpdater.decrementAndGet(this); + return false; + } + else + { + return true; + } + } + + /** + * Threadsafe. This will decrement the reference count and when it reaches zero will remove the message from the + * message store. + * + * + * @throws org.apache.qpid.server.queue.MessageCleanupException when an attempt was made to remove the message from the message store and that + * failed + */ + public void decrementReference() + { + int count = _refCountUpdater.decrementAndGet(this); + + // note that the operation of decrementing the reference count and then removing the message does not + // have to be atomic since the ref count starts at 1 and the exchange itself decrements that after + // the message has been passed to all queues. i.e. we are + // not relying on the all the increments having taken place before the delivery manager decrements. + if (count == 0) + { + // set the reference count way below 0 so that we can detect that the message has been deleted + // this is to guard against the message being spontaneously recreated (from the mgmt console) + // by copying from other queues at the same time as it is being removed. + _refCountUpdater.set(this,Integer.MIN_VALUE/2); + + // must check if the handle is null since there may be cases where we decide to throw away a message + // and the handle has not yet been constructed + if (_storedMessage != null) + { + _storedMessage.remove(); + } + } + else + { + if (count < 0) + { + throw new RuntimeException("Reference count for message id " + getMessageNumber() + + " has gone below 0."); + } + } } public static class Reference extends MessageReference<Message_1_0> @@ -160,13 +244,13 @@ public class Message_1_0 implements ServerMessage, InboundMessage protected void onReference(Message_1_0 message) { - + message.incrementReference(); } protected void onRelease(Message_1_0 message) { - + message.decrementReference(); } -} + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java index 999ffc55e5..a0ed824c58 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java @@ -36,7 +36,6 @@ import org.apache.qpid.amqp_1_0.type.transport.*; import org.apache.qpid.amqp_1_0.type.transport.Error; import org.apache.qpid.AMQException; import org.apache.qpid.AMQSecurityException; -import org.apache.qpid.protocol.ProtocolEngine; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.message.InboundMessage; @@ -45,8 +44,6 @@ import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.registry.IApplicationRegistry; -import org.apache.qpid.server.transport.ServerConnection; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -58,7 +55,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_F public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSubject { private static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy"); - private IApplicationRegistry _appRegistry; private VirtualHost _vhost; private AutoCommitTransaction _transaction; @@ -68,9 +64,8 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu private UUID _id = UUID.randomUUID(); - public Session_1_0(VirtualHost vhost, IApplicationRegistry appRegistry, final Connection_1_0 connection) + public Session_1_0(VirtualHost vhost, final Connection_1_0 connection) { - _appRegistry = appRegistry; _vhost = vhost; _transaction = new AutoCommitTransaction(vhost.getMessageStore()); _connection = connection; @@ -456,8 +451,9 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu { } + @Override - public UUID getQMFId() + public UUID getId() { return _id; } @@ -580,13 +576,6 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu return 0; } - @Override - public int compareTo(AMQSessionModel o) - { - return getQMFId().compareTo(o.getQMFId()); - } - - public String toLogString() { @@ -604,4 +593,9 @@ public class Session_1_0 implements SessionEventListener, AMQSessionModel, LogSu + "] "; } + @Override + public int compareTo(AMQSessionModel o) + { + return getId().compareTo(o.getId()); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java index d3efd63ee0..4f610cc925 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java @@ -23,8 +23,7 @@ package org.apache.qpid.server.queue; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.QueueConfig; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.QueueConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeReferrer; import org.apache.qpid.server.logging.LogSubject; @@ -39,9 +38,10 @@ import java.util.List; import java.util.Map; import java.util.Set; -public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue, - QueueConfig +public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, TransactionLogResource, BaseQueue { + String getName(); + public interface NotificationListener { void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg); @@ -277,9 +277,7 @@ public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, Transa public void doTask(AMQQueue queue) throws AMQException; } - void configure(ConfigurationPlugin config); - - ConfigurationPlugin getConfiguration(); + void configure(QueueConfiguration config); void setExclusive(boolean exclusive); @@ -315,4 +313,18 @@ public interface AMQQueue extends Comparable<AMQQueue>, ExchangeReferrer, Transa */ String getDescription(); + long getPersistentByteDequeues(); + + long getPersistentMsgDequeues(); + + long getPersistentByteEnqueues(); + + long getPersistentMsgEnqueues(); + + long getTotalDequeueSize(); + + long getTotalEnqueueSize(); + + long getUnackedMessageCount(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java index 3a18fae2ec..a65a6a8eb2 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java @@ -30,17 +30,25 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.exchange.DefaultExchangeFactory; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.virtualhost.VirtualHost; public class AMQQueueFactory { + public static final String X_QPID_FLOW_RESUME_CAPACITY = "x-qpid-flow-resume-capacity"; + public static final String X_QPID_CAPACITY = "x-qpid-capacity"; + public static final String X_QPID_MINIMUM_ALERT_REPEAT_GAP = "x-qpid-minimum-alert-repeat-gap"; + public static final String X_QPID_MAXIMUM_MESSAGE_COUNT = "x-qpid-maximum-message-count"; + public static final String X_QPID_MAXIMUM_MESSAGE_SIZE = "x-qpid-maximum-message-size"; + public static final String X_QPID_MAXIMUM_MESSAGE_AGE = "x-qpid-maximum-message-age"; + public static final String X_QPID_MAXIMUM_QUEUE_DEPTH = "x-qpid-maximum-queue-depth"; + public static final String X_QPID_PRIORITIES = "x-qpid-priorities"; public static final String X_QPID_DESCRIPTION = "x-qpid-description"; public static final String QPID_LVQ_KEY = "qpid.LVQ_key"; @@ -119,42 +127,49 @@ public class AMQQueueFactory } private static final QueueProperty[] DECLAREABLE_PROPERTIES = { - new QueueLongProperty("x-qpid-maximum-message-age") + new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_AGE) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMaximumMessageAge(value); } }, - new QueueLongProperty("x-qpid-maximum-message-size") + new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_SIZE) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMaximumMessageSize(value); } }, - new QueueLongProperty("x-qpid-maximum-message-count") + new QueueLongProperty(X_QPID_MAXIMUM_MESSAGE_COUNT) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMaximumMessageCount(value); } }, - new QueueLongProperty("x-qpid-minimum-alert-repeat-gap") + new QueueLongProperty(X_QPID_MAXIMUM_QUEUE_DEPTH) + { + public void setPropertyValue(AMQQueue queue, long value) + { + queue.setMaximumQueueDepth(value); + } + }, + new QueueLongProperty(X_QPID_MINIMUM_ALERT_REPEAT_GAP) { public void setPropertyValue(AMQQueue queue, long value) { queue.setMinimumAlertRepeatGap(value); } }, - new QueueLongProperty("x-qpid-capacity") + new QueueLongProperty(X_QPID_CAPACITY) { public void setPropertyValue(AMQQueue queue, long value) { queue.setCapacity(value); } }, - new QueueLongProperty("x-qpid-flow-resume-capacity") + new QueueLongProperty(X_QPID_FLOW_RESUME_CAPACITY) { public void setPropertyValue(AMQQueue queue, long value) { @@ -411,9 +426,7 @@ public class AMQQueueFactory */ protected static String getDeadLetterQueueName(String name) { - ServerConfiguration serverConfig = ApplicationRegistry.getInstance().getConfiguration(); - String dlQueueName = name + serverConfig.getDeadLetterQueueSuffix(); - return dlQueueName; + return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_QUEUE_SUFFIX, DEFAULT_DLQ_NAME_SUFFIX); } /** @@ -425,9 +438,7 @@ public class AMQQueueFactory */ protected static String getDeadLetterExchangeName(String name) { - ServerConfiguration serverConfig = ApplicationRegistry.getInstance().getConfiguration(); - String dlExchangeName = name + serverConfig.getDeadLetterExchangeSuffix(); - return dlExchangeName; + return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, DefaultExchangeFactory.DEFAULT_DLE_NAME_SUFFIX); } private static Map<String, Object> createQueueArgumentsFromConfig(QueueConfiguration config) diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java index bbc33ca846..d7dbd58537 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/InboundMessageAdapter.java @@ -47,7 +47,7 @@ public class InboundMessageAdapter implements InboundMessage public AMQShortString getRoutingKeyShortString() { - return AMQShortString.valueOf(_entry.getMessage()); + return AMQShortString.valueOf(_entry.getMessage().getRoutingKey()); } public String getRoutingKey() diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java index c5a610c7b6..18affc7161 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java @@ -34,7 +34,6 @@ import org.apache.qpid.server.message.EnqueableMessage; import org.apache.qpid.server.message.InboundMessage; import org.apache.qpid.server.message.MessageContentSource; import org.apache.qpid.server.message.MessageMetaData; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.store.StoredMessage; import java.nio.ByteBuffer; @@ -47,9 +46,6 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes /** Used for debugging purposes. */ private static final Logger _logger = Logger.getLogger(IncomingMessage.class); - private static final boolean SYNCHED_CLOCKS = - ApplicationRegistry.getInstance().getConfiguration().getSynchedClocks(); - private final MessagePublishInfo _messagePublishInfo; private ContentHeaderBody _contentHeaderBody; @@ -101,33 +97,7 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes public void setExpiration() { - long expiration = - ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration(); - long timestamp = - ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getTimestamp(); - - if (SYNCHED_CLOCKS) - { - _expiration = expiration; - } - else - { - // Update TTL to be in broker time. - if (expiration != 0L) - { - if (timestamp != 0L) - { - // todo perhaps use arrival time - long diff = (System.currentTimeMillis() - timestamp); - - if ((diff > 1000L) || (diff < 1000L)) - { - _expiration = expiration + diff; - } - } - } - } - + _expiration = ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration(); } public MessageMetaData headersReceived(long currentTime) diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java index 25e771a9cf..9aa8d1da83 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java @@ -454,7 +454,7 @@ public abstract class QueueEntryImpl implements QueueEntry { } - }, 0L); + }); txn.dequeue(currentQueue, message, new ServerTransaction.Action() { diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java index d42bd6cf03..73c2870b9b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java @@ -41,11 +41,8 @@ import org.apache.qpid.AMQSecurityException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.pool.ReferenceCountingExecutorService; import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.QueueConfigType; import org.apache.qpid.server.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.plugins.AbstractConfiguration; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; @@ -55,7 +52,6 @@ import org.apache.qpid.server.logging.messages.QueueMessages; import org.apache.qpid.server.logging.subjects.QueueLogSubject; import org.apache.qpid.server.message.ServerMessage; import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.AuthorizationHolder; import org.apache.qpid.server.subscription.AssignedSubscriptionMessageGroupManager; import org.apache.qpid.server.subscription.DefinedGroupMessageGroupManager; @@ -135,23 +131,23 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes private final AtomicInteger _bindingCountHigh = new AtomicInteger(); /** max allowed size(KB) of a single message */ - private long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize(); + private long _maximumMessageSize; /** max allowed number of messages on a queue. */ - private long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount(); + private long _maximumMessageCount; /** max queue depth for the queue */ - private long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth(); + private long _maximumQueueDepth; /** maximum message age before alerts occur */ - private long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge(); + private long _maximumMessageAge; /** the minimum interval between sending out consecutive alerts of the same type */ - private long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap(); + private long _minimumAlertRepeatGap; - private long _capacity = ApplicationRegistry.getInstance().getConfiguration().getCapacity(); + private long _capacity; - private long _flowResumeCapacity = ApplicationRegistry.getInstance().getConfiguration().getFlowResumeCapacity(); + private long _flowResumeCapacity; private final Set<NotificationCheck> _notificationChecks = EnumSet.noneOf(NotificationCheck.class); @@ -185,11 +181,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes //TODO : persist creation time private long _createTime = System.currentTimeMillis(); - private UUID _qmfId; - private ConfigurationPlugin _queueConfiguration; + private AbstractConfiguration _queueConfiguration; /** the maximum delivery count for each message on this queue or 0 if maximum delivery count is not to be enforced. */ - private int _maximumDeliveryCount = ApplicationRegistry.getInstance().getConfiguration().getMaxDeliveryCount(); + private int _maximumDeliveryCount; private final MessageGroupManager _messageGroupManager; private final Collection<SubscriptionRegistrationListener> _subscriptionListeners = @@ -243,7 +238,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes _arguments = arguments == null ? new HashMap<String, Object>() : new HashMap<String, Object>(arguments); _id = id; - _qmfId = getConfigStore().createId(); _asyncDelivery = ReferenceCountingExecutorService.getInstance().acquireExecutorService(); _logSubject = new QueueLogSubject(this); @@ -259,8 +253,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes durable, !durable, _entries.getPriorities() > 0)); - getConfigStore().addConfiguredObject(this); - if(arguments != null && arguments.containsKey(QPID_GROUP_HEADER_KEY)) { if(arguments.containsKey(QPID_SHARED_MSG_GROUP) && String.valueOf(arguments.get(QPID_SHARED_MSG_GROUP)).equals("1")) @@ -331,22 +323,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes return _id; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public QueueConfigType getConfigType() - { - return QueueConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); - } - public boolean isDurable() { return _durable; @@ -621,24 +597,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes break; } } - - reconfigure(); - } - - private void reconfigure() - { - //Reconfigure the queue for to reflect this new binding. - ConfigurationPlugin config = getVirtualHost().getConfiguration().getQueueConfiguration(this); - - if (config != null) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("Reconfiguring queue(" + this + ") with config:" + config + " was "+ _queueConfiguration); - } - // Reconfigure with new config. - configure(config); - } } public int getBindingCountHigh() @@ -649,8 +607,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes public void removeBinding(final Binding binding) { _bindings.remove(binding); - - reconfigure(); } public List<Binding> getBindings() @@ -1383,7 +1339,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } _virtualHost.getQueueRegistry().unregisterQueue(_name); - getConfigStore().removeConfiguredObject(this); List<QueueEntry> entries = getMessagesOnTheQueue(new QueueEntryFilter() { @@ -1442,7 +1397,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes { } - }, 0L); + }); txn.dequeue(this, entry.getMessage(), new ServerTransaction.Action() { @@ -2161,39 +2116,21 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } - public void configure(ConfigurationPlugin config) + public void configure(QueueConfiguration config) { if (config != null) { - if (config instanceof QueueConfiguration) - { - - setMaximumMessageAge(((QueueConfiguration)config).getMaximumMessageAge()); - setMaximumQueueDepth(((QueueConfiguration)config).getMaximumQueueDepth()); - setMaximumMessageSize(((QueueConfiguration)config).getMaximumMessageSize()); - setMaximumMessageCount(((QueueConfiguration)config).getMaximumMessageCount()); - setMinimumAlertRepeatGap(((QueueConfiguration)config).getMinimumAlertRepeatGap()); - setMaximumDeliveryCount(((QueueConfiguration)config).getMaxDeliveryCount()); - _capacity = ((QueueConfiguration)config).getCapacity(); - _flowResumeCapacity = ((QueueConfiguration)config).getFlowResumeCapacity(); - } - - _queueConfiguration = config; - + setMaximumMessageAge(config.getMaximumMessageAge()); + setMaximumQueueDepth(config.getMaximumQueueDepth()); + setMaximumMessageSize(config.getMaximumMessageSize()); + setMaximumMessageCount(config.getMaximumMessageCount()); + setMinimumAlertRepeatGap(config.getMinimumAlertRepeatGap()); + setMaximumDeliveryCount(config.getMaxDeliveryCount()); + _capacity = config.getCapacity(); + _flowResumeCapacity = config.getFlowResumeCapacity(); } } - - public ConfigurationPlugin getConfiguration() - { - return _queueConfiguration; - } - - public ConfigStore getConfigStore() - { - return getVirtualHost().getConfigStore(); - } - public long getMessageDequeueCount() { return _dequeueCount.get(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java index e0e317f75d..1379b375cf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java @@ -20,44 +20,39 @@ */ package org.apache.qpid.server.registry; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.logging.*; -import org.osgi.framework.BundleContext; +import java.util.Collection; +import java.util.Timer; +import java.util.TimerTask; +import org.apache.log4j.Logger; import org.apache.qpid.common.Closeable; import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.qmf.QMFService; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfigurationManager; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.SystemConfig; -import org.apache.qpid.server.configuration.SystemConfigImpl; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.configuration.ConfigurationEntryStore; +import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; +import org.apache.qpid.server.configuration.RecovererProvider; +import org.apache.qpid.server.configuration.startup.DefaultRecovererProvider; +import org.apache.qpid.server.logging.CompositeStartupMessageLogger; +import org.apache.qpid.server.logging.Log4jMessageLogger; +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.logging.RootMessageLogger; +import org.apache.qpid.server.logging.SystemOutMessageLogger; import org.apache.qpid.server.logging.actors.AbstractActor; import org.apache.qpid.server.logging.actors.BrokerActor; import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.actors.GenericActor; import org.apache.qpid.server.logging.messages.BrokerMessages; import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.adapter.BrokerAdapter; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManagerRegistry; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.stats.StatisticsCounter; -import org.apache.qpid.server.transport.QpidAcceptor; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostImpl; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.*; -import java.util.concurrent.atomic.AtomicReference; - /** * An abstract application registry that provides access to configuration information and handles the @@ -65,321 +60,90 @@ import java.util.concurrent.atomic.AtomicReference; * <p/> * Subclasses should handle the construction of the "registered objects" such as the exchange registry. */ -public abstract class ApplicationRegistry implements IApplicationRegistry +public class ApplicationRegistry implements IApplicationRegistry { - private static final Logger _logger = Logger.getLogger(ApplicationRegistry.class); - private static AtomicReference<IApplicationRegistry> _instance = new AtomicReference<IApplicationRegistry>(null); - - private final ServerConfiguration _configuration; - - private final Map<InetSocketAddress, QpidAcceptor> _acceptors = - Collections.synchronizedMap(new HashMap<InetSocketAddress, QpidAcceptor>()); - - private IAuthenticationManagerRegistry _authenticationManagerRegistry; - - private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(this); - - private SecurityManager _securityManager; + private final VirtualHostRegistry _virtualHostRegistry = new VirtualHostRegistry(); - private PluginManager _pluginManager; - - private ConfigurationManager _configurationManager; - - private RootMessageLogger _rootMessageLogger; - - private CompositeStartupMessageLogger _startupMessageLogger; - - private UUID _brokerId = UUID.randomUUID(); - - private QMFService _qmfService; - - private BrokerConfig _brokerConfig; + private volatile RootMessageLogger _rootMessageLogger; private Broker _broker; - private ConfigStore _configStore; - private Timer _reportingTimer; private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived; - private BundleContext _bundleContext; - - private final List<PortBindingListener> _portBindingListeners = new ArrayList<PortBindingListener>(); - - private int _httpManagementPort = -1, _httpsManagementPort = -1; - private LogRecorder _logRecorder; - private List<IAuthenticationManagerRegistry.RegistryChangeListener> _authManagerChangeListeners = - new ArrayList<IAuthenticationManagerRegistry.RegistryChangeListener>(); - - public Map<InetSocketAddress, QpidAcceptor> getAcceptors() - { - synchronized (_acceptors) - { - return new HashMap<InetSocketAddress, QpidAcceptor>(_acceptors); - } - } - - protected void setSecurityManager(SecurityManager securityManager) - { - _securityManager = securityManager; - } - - protected void setPluginManager(PluginManager pluginManager) - { - _pluginManager = pluginManager; - } - - protected void setConfigurationManager(ConfigurationManager configurationManager) - { - _configurationManager = configurationManager; - } + private ConfigurationEntryStore _store; + private TaskExecutor _taskExecutor; protected void setRootMessageLogger(RootMessageLogger rootMessageLogger) { _rootMessageLogger = rootMessageLogger; } - protected CompositeStartupMessageLogger getStartupMessageLogger() - { - return _startupMessageLogger; - } - - protected void setStartupMessageLogger(CompositeStartupMessageLogger startupMessageLogger) + public ApplicationRegistry(ConfigurationEntryStore store) { - _startupMessageLogger = startupMessageLogger; - } - - protected void setBrokerId(UUID brokerId) - { - _brokerId = brokerId; - } - - protected QMFService getQmfService() - { - return _qmfService; - } - - protected void setQmfService(QMFService qmfService) - { - _qmfService = qmfService; - } - - public static void initialise(IApplicationRegistry instance) throws Exception - { - if(instance == null) - { - throw new IllegalArgumentException("ApplicationRegistry instance must not be null"); - } - - if(!_instance.compareAndSet(null, instance)) - { - throw new IllegalStateException("An ApplicationRegistry is already initialised"); - } - - _logger.info("Initialising Application Registry(" + instance + ")"); - - - final ConfigStore store = ConfigStore.newInstance(); - store.setRoot(new SystemConfigImpl(store)); - instance.setConfigStore(store); - - final BrokerConfig brokerConfig = new BrokerConfigAdapter(instance); - - final SystemConfig system = store.getRoot(); - system.addBroker(brokerConfig); - instance.setBrokerConfig(brokerConfig); - - try - { - instance.initialise(); - } - catch (Exception e) - { - _instance.set(null); - - //remove the Broker instance, then re-throw - try - { - system.removeBroker(brokerConfig); - } - catch(Throwable t) - { - //ignore - } - - throw e; - } - } - - public ConfigStore getConfigStore() - { - return _configStore; - } - - public void setConfigStore(final ConfigStore configStore) - { - _configStore = configStore; - } - - public static boolean isConfigured() - { - return _instance.get() != null; - } - - public static void remove() - { - IApplicationRegistry instance = _instance.getAndSet(null); - try - { - if (instance != null) - { - if (_logger.isInfoEnabled()) - { - _logger.info("Shutting down ApplicationRegistry(" + instance + ")"); - } - instance.close(); - } - } - catch (Exception e) - { - _logger.error("Error shutting down Application Registry(" + instance + "): " + e, e); - } - } - - protected ApplicationRegistry(ServerConfiguration configuration) - { - this(configuration, null); - } - - protected ApplicationRegistry(ServerConfiguration configuration, BundleContext bundleContext) - { - _configuration = configuration; - _bundleContext = bundleContext; - } - - public void configure() throws ConfigurationException - { - _configurationManager = new ConfigurationManager(); - - try - { - _pluginManager = new PluginManager(_configuration.getPluginDirectory(), _configuration.getCacheDirectory(), _bundleContext); - } - catch (Exception e) - { - throw new ConfigurationException(e); - } - - _configuration.initialise(); + _store = store; + initialiseStatistics(); } public void initialise() throws Exception { + // Create the RootLogger to be used during broker operation + boolean statusUpdatesEnabled = Boolean.parseBoolean(System.getProperty(BrokerProperties.PROPERTY_STATUS_UPDATES, "true")); + _rootMessageLogger = new Log4jMessageLogger(statusUpdatesEnabled); + _logRecorder = new LogRecorder(); - //Create the RootLogger to be used during broker operation - _rootMessageLogger = new Log4jMessageLogger(_configuration); //Create the composite (log4j+SystemOut MessageLogger to be used during startup RootMessageLogger[] messageLoggers = {new SystemOutMessageLogger(), _rootMessageLogger}; - _startupMessageLogger = new CompositeStartupMessageLogger(messageLoggers); + CompositeStartupMessageLogger startupMessageLogger = new CompositeStartupMessageLogger(messageLoggers); - BrokerActor actor = new BrokerActor(_startupMessageLogger); - CurrentActor.setDefault(actor); + BrokerActor actor = new BrokerActor(startupMessageLogger); CurrentActor.set(actor); - + CurrentActor.setDefault(actor); + GenericActor.setDefaultMessageLogger(_rootMessageLogger); try { - initialiseStatistics(); - - if(_configuration.getHTTPManagementEnabled()) - { - _httpManagementPort = _configuration.getHTTPManagementPort(); - } - if (_configuration.getHTTPSManagementEnabled()) - { - _httpsManagementPort = _configuration.getHTTPSManagementPort(); - } - - _broker = new BrokerAdapter(this); - - configure(); - - _qmfService = new QMFService(getConfigStore(), this); - logStartupMessages(CurrentActor.get()); - _securityManager = new SecurityManager(_configuration, _pluginManager); + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); - _authenticationManagerRegistry = createAuthenticationManagerRegistry(_configuration, _pluginManager); + RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor); + ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName()); + _broker = (Broker) brokerRecoverer.create(provider, _store.getRootEntry()); - if(!_authManagerChangeListeners.isEmpty()) - { - for(IAuthenticationManagerRegistry.RegistryChangeListener listener : _authManagerChangeListeners) - { + _virtualHostRegistry.setDefaultVirtualHostName((String)_broker.getAttribute(Broker.DEFAULT_VIRTUAL_HOST)); - _authenticationManagerRegistry.addRegistryChangeListener(listener); - for(AuthenticationManager authMgr : _authenticationManagerRegistry.getAvailableAuthenticationManagers().values()) - { - listener.authenticationManagerRegistered(authMgr); - } - } - _authManagerChangeListeners.clear(); - } - } - finally - { - CurrentActor.remove(); - } - - CurrentActor.set(new BrokerActor(_rootMessageLogger)); - try - { - initialiseVirtualHosts(); initialiseStatisticsReporting(); + + // starting the broker + _broker.setDesiredState(State.INITIALISING, State.ACTIVE); + + CurrentActor.get().message(BrokerMessages.READY()); } finally { - // Startup complete, so pop the current actor CurrentActor.remove(); } - } - protected IAuthenticationManagerRegistry createAuthenticationManagerRegistry(ServerConfiguration _configuration, PluginManager _pluginManager) - throws ConfigurationException - { - return new AuthenticationManagerRegistry(_configuration, _pluginManager); + CurrentActor.setDefault(new BrokerActor(_rootMessageLogger)); } - protected void initialiseVirtualHosts() throws Exception + private void initialiseStatisticsReporting() { - for (String name : _configuration.getVirtualHosts()) - { - createVirtualHost(_configuration.getVirtualHostConfig(name)); - } - getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost()); - } - - public void initialiseStatisticsReporting() - { - long report = _configuration.getStatisticsReportingPeriod() * 1000; // convert to ms - final boolean broker = _configuration.isStatisticsGenerationBrokerEnabled(); - final boolean virtualhost = _configuration.isStatisticsGenerationVirtualhostsEnabled(); - final boolean reset = _configuration.isStatisticsReportResetEnabled(); + long report = ((Number)_broker.getAttribute(Broker.STATISTICS_REPORTING_PERIOD)).intValue() * 1000; // convert to ms + final boolean reset = (Boolean)_broker.getAttribute(Broker.STATISTICS_REPORTING_RESET_ENABLED); /* add a timer task to report statistics if generation is enabled for broker or virtualhosts */ - if (report > 0L && (broker || virtualhost)) + if (report > 0L) { _reportingTimer = new Timer("Statistics-Reporting", true); - - - - _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(broker, virtualhost, reset), - report / 2, - report); + StatisticsReportingTask task = new StatisticsReportingTask(reset, _rootMessageLogger); + _reportingTimer.scheduleAtFixedRate(task, report / 2, report); } } @@ -388,76 +152,62 @@ public abstract class ApplicationRegistry implements IApplicationRegistry private final int DELIVERED = 0; private final int RECEIVED = 1; - private boolean _broker; - private boolean _virtualhost; - private boolean _reset; + private final boolean _reset; + private final RootMessageLogger _logger; - - public StatisticsReportingTask(boolean broker, boolean virtualhost, boolean reset) + public StatisticsReportingTask(boolean reset, RootMessageLogger logger) { - _broker = broker; - _virtualhost = virtualhost; _reset = reset; + _logger = logger; } public void run() { - CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) { + CurrentActor.set(new AbstractActor(_logger) + { public String getLogMessage() { return "[" + Thread.currentThread().getName() + "] "; } }); - - if (_broker) + try { CurrentActor.get().message(BrokerMessages.STATS_DATA(DELIVERED, _dataDelivered.getPeak() / 1024.0, _dataDelivered.getTotal())); CurrentActor.get().message(BrokerMessages.STATS_MSGS(DELIVERED, _messagesDelivered.getPeak(), _messagesDelivered.getTotal())); CurrentActor.get().message(BrokerMessages.STATS_DATA(RECEIVED, _dataReceived.getPeak() / 1024.0, _dataReceived.getTotal())); CurrentActor.get().message(BrokerMessages.STATS_MSGS(RECEIVED, _messagesReceived.getPeak(), _messagesReceived.getTotal())); - } + Collection<VirtualHost> hosts = _virtualHostRegistry.getVirtualHosts(); - if (_virtualhost) - { - for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts()) + if (hosts.size() > 1) { - String name = vhost.getName(); - StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics(); - StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics(); - StatisticsCounter dataReceived = vhost.getDataReceiptStatistics(); - StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics(); - - CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal())); - CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal())); - CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal())); - CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal())); + for (VirtualHost vhost : hosts) + { + String name = vhost.getName(); + StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics(); + StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics(); + StatisticsCounter dataReceived = vhost.getDataReceiptStatistics(); + StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics(); + + CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal())); + CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal())); + CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal())); + CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal())); + } } - } - if (_reset) + if (_reset) + { + resetStatistics(); + } + } + catch(Exception e) { - resetStatistics(); + ApplicationRegistry._logger.warn("Unexpected exception occured while reporting the statistics", e); + } + finally + { + CurrentActor.remove(); } - - CurrentActor.remove(); - } - } - - /** - * Get the ApplicationRegistry - * @return the IApplicationRegistry instance - * @throws IllegalStateException if no registry instance has been initialised. - */ - public static IApplicationRegistry getInstance() throws IllegalStateException - { - IApplicationRegistry iApplicationRegistry = _instance.get(); - if (iApplicationRegistry == null) - { - throw new IllegalStateException("No ApplicationRegistry has been initialised"); - } - else - { - return iApplicationRegistry; } } @@ -488,7 +238,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry } //Set the Actor for Broker Shutdown - CurrentActor.set(new BrokerActor(getRootMessageLogger())); + CurrentActor.set(new BrokerActor(_rootMessageLogger)); try { //Stop Statistics Reporting @@ -497,154 +247,34 @@ public abstract class ApplicationRegistry implements IApplicationRegistry _reportingTimer.cancel(); } - //Stop incoming connections - unbind(); + if (_broker != null) + { + _broker.setDesiredState(_broker.getActualState(), State.STOPPED); + } //Shutdown virtualhosts close(_virtualHostRegistry); - close(_authenticationManagerRegistry); - - close(_qmfService); - - close(_pluginManager); - - BrokerConfig broker = getBrokerConfig(); - if(broker != null) + if (_taskExecutor != null) { - broker.getSystem().removeBroker(broker); + _taskExecutor.stop(); } CurrentActor.get().message(BrokerMessages.STOPPED()); - } - finally - { - CurrentActor.remove(); - } - } - - private void unbind() - { - List<QpidAcceptor> removedAcceptors = new ArrayList<QpidAcceptor>(); - synchronized (_acceptors) - { - for (InetSocketAddress bindAddress : _acceptors.keySet()) - { - QpidAcceptor acceptor = _acceptors.get(bindAddress); - removedAcceptors.add(acceptor); - try - { - acceptor.getNetworkTransport().close(); - } - catch (Throwable e) - { - _logger.error("Unable to close network driver due to:" + e.getMessage()); - } + _logRecorder.closeLogRecorder(); - CurrentActor.get().message(BrokerMessages.SHUTTING_DOWN(acceptor.toString(), bindAddress.getPort())); - } } - synchronized (_portBindingListeners) - { - for(QpidAcceptor acceptor : removedAcceptors) - { - for(PortBindingListener listener : _portBindingListeners) - { - listener.unbound(acceptor); - } - } - } - } - - public ServerConfiguration getConfiguration() - { - return _configuration; - } - - public void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor) - { - synchronized (_acceptors) - { - _acceptors.put(bindAddress, acceptor); - } - synchronized (_portBindingListeners) + finally { - for(PortBindingListener listener : _portBindingListeners) + if (_taskExecutor != null) { - listener.bound(acceptor, bindAddress); + _taskExecutor.stopImmediately(); } + CurrentActor.remove(); } - } - - public VirtualHostRegistry getVirtualHostRegistry() - { - return _virtualHostRegistry; - } - - public SecurityManager getSecurityManager() - { - return _securityManager; - } - - @Override - public AuthenticationManager getAuthenticationManager(SocketAddress address) - { - return _authenticationManagerRegistry.getAuthenticationManager(address); - } - - @Override - public IAuthenticationManagerRegistry getAuthenticationManagerRegistry() - { - return _authenticationManagerRegistry; - } - - public PluginManager getPluginManager() - { - return _pluginManager; - } - - public ConfigurationManager getConfigurationManager() - { - return _configurationManager; - } - - public RootMessageLogger getRootMessageLogger() - { - return _rootMessageLogger; - } - - public RootMessageLogger getCompositeStartupMessageLogger() - { - return _startupMessageLogger; - } - - public UUID getBrokerId() - { - return _brokerId; - } - - public QMFService getQMFService() - { - return _qmfService; - } - - public BrokerConfig getBrokerConfig() - { - return _brokerConfig; - } - - public void setBrokerConfig(final BrokerConfig broker) - { - _brokerConfig = broker; - } - - public VirtualHost createVirtualHost(final VirtualHostConfiguration vhostConfig) throws Exception - { - VirtualHostImpl virtualHost = new VirtualHostImpl(this, vhostConfig); - _virtualHostRegistry.registerVirtualHost(virtualHost); - getBrokerConfig().addVirtualHost(virtualHost); - return virtualHost; + _store = null; + _broker = null; } public void registerMessageDelivered(long messageSize) @@ -713,60 +343,10 @@ public abstract class ApplicationRegistry implements IApplicationRegistry logActor.message(BrokerMessages.MAX_MEMORY(Runtime.getRuntime().maxMemory())); } + @Override public Broker getBroker() { return _broker; } - @Override - public void addPortBindingListener(PortBindingListener listener) - { - synchronized (_portBindingListeners) - { - _portBindingListeners.add(listener); - } - } - - - @Override - public boolean useHTTPManagement() - { - return _httpManagementPort != -1; - } - - @Override - public int getHTTPManagementPort() - { - return _httpManagementPort; - } - - @Override - public boolean useHTTPSManagement() - { - return _httpsManagementPort != -1; - } - - @Override - public int getHTTPSManagementPort() - { - return _httpsManagementPort; - } - - public LogRecorder getLogRecorder() - { - return _logRecorder; - } - - @Override - public void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener) - { - if(_authenticationManagerRegistry == null) - { - _authManagerChangeListeners.add(registryChangeListener); - } - else - { - _authenticationManagerRegistry.addRegistryChangeListener(registryChangeListener); - } - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java deleted file mode 100644 index 950a090b43..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.registry; - -import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.common.ServerPropertyNames; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.BrokerConfigType; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.SystemConfig; -import org.apache.qpid.server.configuration.VirtualHostConfig; -import org.apache.qpid.server.virtualhost.VirtualHost; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public class BrokerConfigAdapter implements BrokerConfig -{ - private final IApplicationRegistry _instance; - private SystemConfig _system; - - private final Map<UUID, VirtualHostConfig> _vhosts = new ConcurrentHashMap<UUID, VirtualHostConfig>(); - private final long _createTime = System.currentTimeMillis(); - private UUID _qmfId; - private String _federationTag; - - public BrokerConfigAdapter(final IApplicationRegistry instance) - { - _instance = instance; - _qmfId = instance.getConfigStore().createId(); - _federationTag = UUID.randomUUID().toString(); - } - - public void setSystem(final SystemConfig system) - { - _system = system; - } - - public SystemConfig getSystem() - { - return _system; - } - - public Integer getPort() - { - List ports = _instance.getConfiguration().getPorts(); - if(ports.size() > 0) - { - return Integer.valueOf(ports.get(0).toString()); - } - else - { - return 0; - } - } - - public Integer getWorkerThreads() - { - return _instance.getConfiguration().getConnectorProcessors(); - } - - public Integer getMaxConnections() - { - return 0; - } - - public Integer getConnectionBacklogLimit() - { - return 0; - } - - public Long getStagingThreshold() - { - return 0L; - } - - public Integer getManagementPublishInterval() - { - return 10000; - } - - public String getVersion() - { - return QpidProperties.getReleaseVersion() + " [Build: " + QpidProperties.getBuildVersion() + "]"; - } - - public String getDataDirectory() - { - return _instance.getConfiguration().getQpidWork(); - } - - public void addVirtualHost(final VirtualHostConfig virtualHost) - { - _vhosts.put(virtualHost.getQMFId(), virtualHost); - getConfigStore().addConfiguredObject(virtualHost); - - } - - private ConfigStore getConfigStore() - { - return _instance.getConfigStore(); - } - - public long getCreateTime() - { - return _createTime; - } - - public void createBrokerConnection(final String transport, - final String host, - final int port, - final boolean durable, - final String authMechanism, - final String username, - final String password) - { - VirtualHost vhost = _instance.getVirtualHostRegistry().getDefaultVirtualHost(); - vhost.createBrokerConnection(transport, host, port, "", durable, authMechanism, username, password); - } - - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public BrokerConfigType getConfigType() - { - return BrokerConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return _system; - } - - public boolean isDurable() - { - return false; - } - - public String getFederationTag() - { - return _federationTag; - } - - /** - * @see org.apache.qpid.server.configuration.BrokerConfig#getFeatures() - */ - public List<String> getFeatures() - { - final List<String> features = new ArrayList<String>(); - if (!_instance.getConfiguration().getDisabledFeatures().contains(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR)) - { - features.add(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR); - } - - return Collections.unmodifiableList(features); - } - - @Override - public String toString() - { - return "BrokerConfigAdapter{" + - "_id=" + _qmfId + - ", _system=" + _system + - ", _vhosts=" + _vhosts + - ", _createTime=" + _createTime + - ", _federationTag='" + _federationTag + '\'' + - '}'; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java deleted file mode 100644 index 774d0338ef..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.registry; - -import org.apache.commons.configuration.ConfigurationException; -import org.osgi.framework.BundleContext; - -import org.apache.qpid.AMQException; -import org.apache.qpid.server.configuration.ServerConfiguration; - -import java.io.File; - -public class ConfigurationFileApplicationRegistry extends ApplicationRegistry -{ - public ConfigurationFileApplicationRegistry(File configurationURL) throws ConfigurationException - { - this(configurationURL, null); - } - - public ConfigurationFileApplicationRegistry(File configurationURL, BundleContext bundleContext) throws ConfigurationException - { - super(new ServerConfiguration(configurationURL), bundleContext); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java index 88c3c93156..d12258d194 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java @@ -20,27 +20,8 @@ */ package org.apache.qpid.server.registry; -import org.apache.qpid.qmf.QMFService; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfigurationManager; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.configuration.VirtualHostConfiguration; -import org.apache.qpid.server.logging.RootMessageLogger; import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.IAuthenticationManagerRegistry; import org.apache.qpid.server.stats.StatisticsGatherer; -import org.apache.qpid.server.transport.QpidAcceptor; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Map; -import java.util.UUID; public interface IApplicationRegistry extends StatisticsGatherer { @@ -56,80 +37,5 @@ public interface IApplicationRegistry extends StatisticsGatherer */ void close(); - /** - * Get the low level configuration. For use cases where the configured object approach is not required - * you can get the complete configuration information. - * @return a Commons Configuration instance - */ - ServerConfiguration getConfiguration(); - - /** - * Get the AuthenticationManager for the given socket address - * - * If no AuthenticationManager has been specifically set for the given address, then use the default - * AuthenticationManager - * - * @param address The (listening) socket address for which the AuthenticationManager is required - * @return the AuthenticationManager - */ - AuthenticationManager getAuthenticationManager(SocketAddress address); - - IAuthenticationManagerRegistry getAuthenticationManagerRegistry(); - - VirtualHostRegistry getVirtualHostRegistry(); - - SecurityManager getSecurityManager(); - - PluginManager getPluginManager(); - - ConfigurationManager getConfigurationManager(); - - RootMessageLogger getRootMessageLogger(); - - /** - * Register any acceptors for this registry - * @param bindAddress The address that the acceptor has been bound with - * @param acceptor The acceptor in use - */ - void addAcceptor(InetSocketAddress bindAddress, QpidAcceptor acceptor); - - public UUID getBrokerId(); - - QMFService getQMFService(); - - void setBrokerConfig(BrokerConfig broker); - - BrokerConfig getBrokerConfig(); - Broker getBroker(); - - VirtualHost createVirtualHost(VirtualHostConfiguration vhostConfig) throws Exception; - - ConfigStore getConfigStore(); - - void setConfigStore(ConfigStore store); - - void initialiseStatisticsReporting(); - - Map<InetSocketAddress, QpidAcceptor> getAcceptors(); - - void addPortBindingListener(PortBindingListener listener); - - boolean useHTTPManagement(); - - int getHTTPManagementPort(); - - boolean useHTTPSManagement(); - - int getHTTPSManagementPort(); - - void addRegistryChangeListener(IAuthenticationManagerRegistry.RegistryChangeListener registryChangeListener); - - public interface PortBindingListener - { - public void bound(QpidAcceptor acceptor, InetSocketAddress bindAddress); - public void unbound(QpidAcceptor acceptor); - - } - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java deleted file mode 100644 index 704e50da5c..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.ObjectType; -import org.apache.qpid.server.security.access.Operation; - -/** - * This is intended as the parent for all simple plugins. - */ -public abstract class AbstractPlugin implements SecurityPlugin -{ - private final Logger _logger = Logger.getLogger(getClass()); - - private ConfigurationPlugin _config; - - public Result getDefault() - { - return Result.ABSTAIN; - } - - public abstract Result access(ObjectType object, Object instance); - - public abstract Result authorise(Operation operation, ObjectType object, ObjectProperties properties); - - public void configure(ConfigurationPlugin config) - { - _config = config; - } - - public ConfigurationPlugin getConfig() - { - return _config; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java deleted file mode 100644 index 236931e8cd..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security; - -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.ObjectType; -import org.apache.qpid.server.security.access.Operation; - -/** - * This {@link SecurityPlugin} proxies the authorise calls to a serries of methods, one per {@link Operation}. - * - */ -public abstract class AbstractProxyPlugin extends AbstractPlugin -{ - public Result authoriseConsume(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authorisePublish(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseCreate(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseAccess(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseBind(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseUnbind(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseDelete(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authorisePurge(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result authoriseUpdate(ObjectType object, ObjectProperties properties) - { - return getDefault(); - } - - public Result accessVirtualhost(Object instance) - { - return getDefault(); - } - - @Override - public Result access(ObjectType objectType, Object instance) - { - switch (objectType) - { - case VIRTUALHOST: - return accessVirtualhost(instance); - } - - return getDefault(); - } - - @Override - public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties) - { - switch (operation) - { - case CONSUME: - return authoriseConsume(objectType, properties); - case PUBLISH: - return authorisePublish(objectType, properties); - case CREATE: - return authoriseCreate(objectType, properties); - case ACCESS: - return authoriseAccess(objectType, properties); - case BIND: - return authoriseBind(objectType, properties); - case UNBIND: - return authoriseUnbind(objectType, properties); - case DELETE: - return authoriseDelete(objectType, properties); - case PURGE: - return authorisePurge(objectType, properties); - case UPDATE: - return authoriseUpdate(objectType, properties); - } - - return getDefault(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java index c3c06bf206..b4831f83e5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/AccessControl.java @@ -18,28 +18,26 @@ */ package org.apache.qpid.server.security; -import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; /** - * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)}, - * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made - * by this plugin. + * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)}, + * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made. */ -public interface SecurityPlugin extends Plugin -{ +public interface AccessControl +{ /** * Default result for {@link #access(ObjectType, Object)} or {@link #authorise(Operation, ObjectType, ObjectProperties)}. */ Result getDefault(); - + /** * Authorise access granted to an object instance. */ Result access(ObjectType objectType, Object instance); - + /** * Authorise an operation on an object defined by a set of properties. */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java index 8f3bdf7738..8243fc3f75 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java @@ -24,14 +24,14 @@ import javax.security.auth.Subject; import java.security.Principal; /** - * Represents the authorization of the logged on user. - * + * Represents the authorization of the logged on user. + * */ public interface AuthorizationHolder { - /** + /** * Returns the {@link Subject} of the authorized user. This is guaranteed to - * contain at least one {@link org.apache.qpid.server.security.auth.sasl.UsernamePrincipal}, representing the the identity + * contain at least one {@link org.apache.qpid.server.security.auth.UsernamePrincipal}, representing the the identity * used when the user logged on to the application, and zero or more {@link org.apache.qpid.server.security.auth.sasl.GroupPrincipal} * representing the group(s) to which the user belongs. * @@ -39,10 +39,10 @@ public interface AuthorizationHolder */ Subject getAuthorizedSubject(); - /** + /** * Returns the {@link Principal} representing the the identity * used when the user logged on to the application. - * + * * @return a Principal */ Principal getAuthorizedPrincipal(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java index 436660cfaf..1a1cce171b 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java @@ -18,22 +18,23 @@ */ package org.apache.qpid.server.security; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.plugins.PluginManager; + +import org.apache.qpid.server.plugin.AccessControlFactory; +import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.security.access.ObjectProperties; +import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE; +import static org.apache.qpid.server.security.access.ObjectType.GROUP; import static org.apache.qpid.server.security.access.ObjectType.METHOD; import static org.apache.qpid.server.security.access.ObjectType.QUEUE; +import static org.apache.qpid.server.security.access.ObjectType.USER; import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST; import static org.apache.qpid.server.security.access.Operation.BIND; import static org.apache.qpid.server.security.access.Operation.CONSUME; @@ -45,103 +46,105 @@ import static org.apache.qpid.server.security.access.Operation.UNBIND; import javax.security.auth.Subject; import java.net.SocketAddress; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; /** - * The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based + * The security manager contains references to all loaded {@link AccessControl}s and delegates security decisions to them based * on virtual host name. The plugins can be external <em>OSGi</em> .jar files that export the required classes or just internal * objects for simpler plugins. - * - * @see SecurityPlugin + * + * @see AccessControl */ public class SecurityManager { private static final Logger _logger = Logger.getLogger(SecurityManager.class); - + /** Container for the {@link java.security.Principal} that is using to this thread. */ private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>(); - private static final ThreadLocal<Boolean> _accessChecksDisabled = new ThreadLocal<Boolean>() + + public static final ThreadLocal<Boolean> _accessChecksDisabled = new ClearingThreadLocal(false); + + private Map<String, AccessControl> _globalPlugins = new HashMap<String, AccessControl>(); + private Map<String, AccessControl> _hostPlugins = new HashMap<String, AccessControl>(); + + /** + * A special ThreadLocal, which calls remove() on itself whenever the value is + * the default, to avoid leaving a default value set after its use has passed. + */ + private static final class ClearingThreadLocal extends ThreadLocal<Boolean> { - protected Boolean initialValue() + private Boolean _defaultValue; + + public ClearingThreadLocal(Boolean defaultValue) { - return false; + super(); + _defaultValue = defaultValue; } - }; - private PluginManager _pluginManager; - private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>(); - private Map<String, SecurityPlugin> _globalPlugins = new HashMap<String, SecurityPlugin>(); - private Map<String, SecurityPlugin> _hostPlugins = new HashMap<String, SecurityPlugin>(); + @Override + protected Boolean initialValue() + { + return _defaultValue; + } - public static class SecurityConfiguration extends ConfigurationPlugin - { - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() + @Override + public void set(Boolean value) { - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException + if (value == _defaultValue) { - ConfigurationPlugin instance = new SecurityConfiguration(); - instance.setConfiguration(path, config); - return instance; + super.remove(); } - - public List<String> getParentPaths() + else { - return Arrays.asList("security", "virtualhosts.virtualhost.security"); + super.set(value); } - }; - - @Override - public String[] getElementsProcessed() - { - return new String[]{"security"}; } - public void validateConfiguration() throws ConfigurationException + @Override + public Boolean get() { - if (getConfig().isEmpty()) + Boolean value = super.get(); + if (value == _defaultValue) { - throw new ConfigurationException("security section is incomplete, no elements found."); + super.remove(); } + return value; } } - - public SecurityManager(SecurityManager parent) throws ConfigurationException + /* + * Used by the VirtualHost to allow deferring to the broker level security plugins if required. + */ + public SecurityManager(SecurityManager parent, String aclFile) { - _pluginManager = parent._pluginManager; - _pluginFactories = parent._pluginFactories; - + this(aclFile); + // our global plugins are the parent's host plugins _globalPlugins = parent._hostPlugins; } - public SecurityManager(ConfigurationPlugin configuration, PluginManager manager) throws ConfigurationException + public SecurityManager(String aclFile) { - this(configuration, manager, null); - } - - public SecurityManager(ConfigurationPlugin configuration, PluginManager manager, SecurityPluginFactory plugin) throws ConfigurationException - { - _pluginManager = manager; - if (manager == null) // No plugin manager, no plugins + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put("aclFile", aclFile); + for (AccessControlFactory provider : (new QpidServiceLoader<AccessControlFactory>()).instancesOf(AccessControlFactory.class)) { - return; + AccessControl accessControl = provider.createInstance(attributes); + if(accessControl != null) + { + addHostPlugin(accessControl); + } } - _pluginFactories = _pluginManager.getSecurityPlugins(); - if (plugin != null) + if(_logger.isDebugEnabled()) { - _pluginFactories.put(plugin.getPluginName(), plugin); + _logger.debug("Configured " + _hostPlugins.size() + " access control plugins"); } - - configureHostPlugins(configuration); } public static Subject getThreadSubject() @@ -154,41 +157,6 @@ public class SecurityManager _subject.set(subject); } - public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException - { - _hostPlugins = configurePlugins(hostConfig); - } - - public void configureGlobalPlugins(ConfigurationPlugin configuration) throws ConfigurationException - { - _globalPlugins = configurePlugins(configuration); - } - - public Map<String, SecurityPlugin> configurePlugins(ConfigurationPlugin hostConfig) throws ConfigurationException - { - Map<String, SecurityPlugin> plugins = new HashMap<String, SecurityPlugin>(); - SecurityConfiguration securityConfig = hostConfig.getConfiguration(SecurityConfiguration.class.getName()); - - // If we have no security Configuration then there is nothing to configure. - if (securityConfig != null) - { - for (SecurityPluginFactory<?> factory : _pluginFactories.values()) - { - SecurityPlugin plugin = factory.newInstance(securityConfig); - if (plugin != null) - { - plugins.put(factory.getPluginName(), plugin); - } - } - } - return plugins; - } - - public void addHostPlugin(SecurityPlugin plugin) - { - _hostPlugins.put(plugin.getClass().getName(), plugin); - } - public static Logger getLogger() { return _logger; @@ -205,7 +173,7 @@ public class SecurityManager private abstract class AccessCheck { - abstract Result allowed(SecurityPlugin plugin); + abstract Result allowed(AccessControl plugin); } private boolean checkAllPlugins(AccessCheck checker) @@ -215,16 +183,16 @@ public class SecurityManager return true; } - Map<String, SecurityPlugin> remainingPlugins = _globalPlugins.isEmpty() - ? Collections.<String, SecurityPlugin>emptyMap() - : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, SecurityPlugin>(_globalPlugins); - - if(!_hostPlugins.isEmpty()) + Map<String, AccessControl> remainingPlugins = _globalPlugins.isEmpty() + ? Collections.<String, AccessControl>emptyMap() + : _hostPlugins.isEmpty() ? _globalPlugins : new HashMap<String, AccessControl>(_globalPlugins); + + if(!_hostPlugins.isEmpty()) { - for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet()) + for (Entry<String, AccessControl> hostEntry : _hostPlugins.entrySet()) { // Create set of global only plugins - SecurityPlugin globalPlugin = remainingPlugins.get(hostEntry.getKey()); + AccessControl globalPlugin = remainingPlugins.get(hostEntry.getKey()); if (globalPlugin != null) { remainingPlugins.remove(hostEntry.getKey()); @@ -272,7 +240,7 @@ public class SecurityManager } } - for (SecurityPlugin plugin : remainingPlugins.values()) + for (AccessControl plugin : remainingPlugins.values()) { Result remaining = checker.allowed(plugin); if (remaining == Result.DEFER) @@ -284,16 +252,16 @@ public class SecurityManager return false; } } - + // getting here means either allowed or abstained from all plugins return true; } - + public boolean authoriseBind(final Exchange exch, final AMQQueue queue, final AMQShortString routingKey) { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(BIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey)); } @@ -304,7 +272,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { ObjectProperties properties = new ObjectProperties(); properties.setName(methodName); @@ -318,11 +286,22 @@ public class SecurityManager }); } + public boolean accessManagement() + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(AccessControl plugin) + { + return plugin.access(ObjectType.MANAGEMENT, null); + } + }); + } + public boolean accessVirtualhost(final String vhostname, final SocketAddress remoteAddress) { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.access(VIRTUALHOST, remoteAddress); } @@ -333,7 +312,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(CONSUME, QUEUE, new ObjectProperties(queue)); } @@ -345,7 +324,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(CREATE, EXCHANGE, new ObjectProperties(autoDelete, durable, exchangeName, internal, nowait, passive, exchangeType)); @@ -358,7 +337,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(CREATE, QUEUE, new ObjectProperties(autoDelete, durable, exclusive, nowait, passive, queueName, owner)); } @@ -369,7 +348,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(DELETE, QUEUE, new ObjectProperties(queue)); } @@ -380,13 +359,34 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(DELETE, EXCHANGE, new ObjectProperties(exchange.getName())); } }); } + public boolean authoriseGroupOperation(final Operation operation, final String groupName) + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(AccessControl plugin) + { + return plugin.authorise(operation, GROUP, new ObjectProperties(groupName)); + } + }); + } + + public boolean authoriseUserOperation(final Operation operation, final String userName) + { + return checkAllPlugins(new AccessCheck() + { + Result allowed(AccessControl plugin) + { + return plugin.authorise(operation, USER, new ObjectProperties(userName)); + } + }); + } private ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>> _immediatePublishPropsCache = new ConcurrentHashMap<String, ConcurrentHashMap<String, PublishAccessCheck>>(); @@ -428,7 +428,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(PURGE, QUEUE, new ObjectProperties(queue)); } @@ -439,7 +439,7 @@ public class SecurityManager { return checkAllPlugins(new AccessCheck() { - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(UNBIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey)); } @@ -465,9 +465,16 @@ public class SecurityManager _props = props; } - Result allowed(SecurityPlugin plugin) + Result allowed(AccessControl plugin) { return plugin.authorise(PUBLISH, EXCHANGE, _props); } } + + + public void addHostPlugin(AccessControl plugin) + { + _hostPlugins.put(plugin.getClass().getName(), plugin); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java deleted file mode 100644 index 21c2d1cda5..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security; - -import org.apache.log4j.Logger; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; - -/** - * An OSGi {@link BundleActivator} that loads a {@link SecurityPluginFactory}. - */ -public abstract class SecurityPluginActivator implements BundleActivator -{ - private static final Logger _logger = Logger.getLogger(SecurityPluginActivator.class); - - private SecurityPluginFactory _factory; - private ConfigurationPluginFactory _config; - private BundleContext _ctx; - private String _bundleName; - - /** Implement this to return the factory this plugin activates. */ - public abstract SecurityPluginFactory getFactory(); - - /** Implement this to return the factory this plugin activates. */ - public abstract ConfigurationPluginFactory getConfigurationFactory(); - - /** - * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) - */ - public void start(BundleContext ctx) throws Exception - { - _ctx = ctx; - _factory = getFactory(); - _config = getConfigurationFactory(); - _bundleName = ctx.getBundle().getSymbolicName(); - - // register the service - _logger.info("Registering security plugin: " + _bundleName); - _ctx.registerService(SecurityPluginFactory.class.getName(), _factory, null); - _ctx.registerService(ConfigurationPluginFactory.class.getName(), _config, null); - } - - /** - * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) - */ - public void stop(BundleContext context) throws Exception - { - _logger.info("Stopping security plugin: " + _bundleName); - - // null object references - _factory = null; - _config = null; - _ctx = null; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java deleted file mode 100644 index fe81cba282..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security; - -import org.apache.qpid.server.plugins.PluginFactory; - -/** - * The factory that generates instances of security plugins. Usually implemented as a static member class in the plugin itself. - */ -public interface SecurityPluginFactory<S extends SecurityPlugin> extends PluginFactory<S> -{ -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java new file mode 100644 index 0000000000..8138745486 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/SubjectCreator.java @@ -0,0 +1,137 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security; + +import java.security.Principal; + +import javax.security.auth.Subject; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.group.GroupPrincipalAccessor; + +/** + * Creates a {@link Subject} formed by the {@link Principal}'s returned from: + * <ol> + * <li>Authenticating using an {@link AuthenticationManager}</li> + * <li>A {@link GroupPrincipalAccessor}</li> + * </ol> + * + * <p> + * SubjectCreator is a facade to the {@link AuthenticationManager}, and is intended to be + * the single place that {@link Subject}'s are created in the broker. + * </p> + */ +public class SubjectCreator +{ + private AuthenticationManager _authenticationManager; + private GroupPrincipalAccessor _groupAccessor; + + public SubjectCreator(AuthenticationManager authenticationManager, GroupPrincipalAccessor groupAccessor) + { + _authenticationManager = authenticationManager; + _groupAccessor = groupAccessor; + } + + /** + * Gets the known SASL mechanisms + * + * @return SASL mechanism names, space separated. + */ + public String getMechanisms() + { + return _authenticationManager.getMechanisms(); + } + + /** + * @see AuthenticationManager#createSaslServer(String, String, Principal) + */ + public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException + { + return _authenticationManager.createSaslServer(mechanism, localFQDN, externalPrincipal); + } + + /** + * Authenticates a user using SASL negotiation. + * + * @param server SASL server + * @param response SASL response to process + */ + public SubjectAuthenticationResult authenticate(SaslServer server, byte[] response) + { + AuthenticationResult authenticationResult = _authenticationManager.authenticate(server, response); + if(server.isComplete()) + { + String username = server.getAuthorizationID(); + + return createResultWithGroups(username, authenticationResult); + } + else + { + return new SubjectAuthenticationResult(authenticationResult); + } + } + + /** + * Authenticates a user using their username and password. + */ + public SubjectAuthenticationResult authenticate(String username, String password) + { + final AuthenticationResult authenticationResult = _authenticationManager.authenticate(username, password); + + return createResultWithGroups(username, authenticationResult); + } + + private SubjectAuthenticationResult createResultWithGroups(String username, final AuthenticationResult authenticationResult) + { + if(authenticationResult.getStatus() == AuthenticationStatus.SUCCESS) + { + final Subject authenticationSubject = new Subject(); + + authenticationSubject.getPrincipals().addAll(authenticationResult.getPrincipals()); + authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username)); + + authenticationSubject.setReadOnly(); + + return new SubjectAuthenticationResult(authenticationResult, authenticationSubject); + } + else + { + return new SubjectAuthenticationResult(authenticationResult); + } + } + + public Subject createSubjectWithGroups(String username) + { + Subject authenticationSubject = new Subject(); + + authenticationSubject.getPrincipals().add(new AuthenticatedPrincipal(username)); + authenticationSubject.getPrincipals().addAll(_groupAccessor.getGroupPrincipals(username)); + authenticationSubject.setReadOnly(); + + return authenticationSubject; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java index a9ec4d1647..8e38681e68 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java @@ -18,33 +18,31 @@ */ package org.apache.qpid.server.security.access; -import org.apache.commons.lang.StringUtils; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.queue.AMQQueue; - import java.util.ArrayList; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; + /** * An set of properties for an access control v2 rule {@link ObjectType}. - * + * * The {@link #matches(ObjectProperties)} method is intended to be used when determining precedence of rules, and * {@link #equals(Object)} and {@link #hashCode()} are intended for use in maps. This is due to the wildcard matching * described above. */ public class ObjectProperties { - /** serialVersionUID */ - private static final long serialVersionUID = -1356019341374170495L; - public static final String STAR= "*"; public static final ObjectProperties EMPTY = new ObjectProperties(); - + public enum Property { ROUTING_KEY, @@ -65,81 +63,89 @@ public class ObjectProperties AUTO_DELETE, COMPONENT, PACKAGE, - CLASS; - - public static Property parse(String text) + CLASS, + FROM_NETWORK, + FROM_HOSTNAME; + + private static final Map<String, Property> _canonicalNameToPropertyMap = new HashMap<String, ObjectProperties.Property>(); + + static { for (Property property : values()) { - if (property.getName().equalsIgnoreCase(text)) - { - return property; - } + _canonicalNameToPropertyMap.put(getCanonicalName(property.name()), property); + } + } + + /** + * Properties are parsed using their canonical name (see {@link #getCanonicalName(String)}) + * so that, for the sake of user-friendliness, the ACL file parses is insensitive to + * case and underscores. + */ + public static Property parse(String text) + { + String propertyName = getCanonicalName(text); + Property property = _canonicalNameToPropertyMap.get(propertyName); + + if(property == null) + { + throw new IllegalArgumentException("Not a valid property: " + text + + " because " + propertyName + + " is not in " + _canonicalNameToPropertyMap.keySet()); + } + else + { + return property; } - throw new IllegalArgumentException("Not a valid property: " + text); } - - public String getName() + + private static String getCanonicalName(String name) { - return StringUtils.remove(name(), '_').toLowerCase(); + return StringUtils.remove(name, '_').toLowerCase(); } - - public static List<String> getPropertyNames() - { - List<String> properties = new ArrayList<String>(); - for (Property property : values()) - { - properties.add(property.getName()); - } - return properties; - } } private final EnumMap<Property, String> _properties = new EnumMap<Property, String>(Property.class); - public static List<String> getAllPropertyNames() + public static List<String> getAllPropertyNames() { - List<String> properties = new ArrayList<String>(); - for (Property property : Property.values()) - { - properties.add(StringUtils.remove(property.name(), '_').toLowerCase()); - } - return properties; - } - + List<String> properties = new ArrayList<String>(); + for (Property property : Property.values()) + { + properties.add(StringUtils.remove(property.name(), '_').toLowerCase()); + } + return properties; + } + public ObjectProperties() { - super(); } - + + public ObjectProperties(Property property, String value) + { + _properties.put(property, value); + } + public ObjectProperties(ObjectProperties copy) { - super(); - _properties.putAll(copy._properties); } - + public ObjectProperties(String name) { - super(); - setName(name); } - + public ObjectProperties(AMQShortString name) { - super(); - setName(name); } - + public ObjectProperties(AMQQueue queue) { - super(); - setName(queue.getName()); - + put(Property.AUTO_DELETE, queue.isAutoDelete()); put(Property.TEMPORARY, queue.isAutoDelete()); put(Property.DURABLE, queue.isDurable()); @@ -157,45 +163,45 @@ public class ObjectProperties put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName()); } } - + public ObjectProperties(Exchange exch, AMQQueue queue, AMQShortString routingKey) { this(queue); - - setName(exch.getName()); - + + setName(exch.getName()); + put(Property.QUEUE_NAME, queue.getName()); put(Property.ROUTING_KEY, routingKey); } - + public ObjectProperties(Exchange exch, AMQShortString routingKey) { this(exch.getName(), routingKey.asString()); } - + public ObjectProperties(String exchangeName, String routingKey, Boolean immediate) { this(exchangeName, routingKey); - + put(Property.IMMEDIATE, immediate); } - + public ObjectProperties(String exchangeName, String routingKey) { super(); - + setName(exchangeName); - + put(Property.ROUTING_KEY, routingKey); } - + public ObjectProperties(Boolean autoDelete, Boolean durable, AMQShortString exchangeName, Boolean internal, Boolean nowait, Boolean passive, AMQShortString exchangeType) { super(); - + setName(exchangeName); - + put(Property.AUTO_DELETE, autoDelete); put(Property.TEMPORARY, autoDelete); put(Property.DURABLE, durable); @@ -204,14 +210,14 @@ public class ObjectProperties put(Property.PASSIVE, passive); put(Property.TYPE, exchangeType); } - + public ObjectProperties(Boolean autoDelete, Boolean durable, Boolean exclusive, Boolean nowait, Boolean passive, AMQShortString queueName, String owner) { super(); - + setName(queueName); - + put(Property.AUTO_DELETE, autoDelete); put(Property.TEMPORARY, autoDelete); put(Property.DURABLE, durable); @@ -220,7 +226,7 @@ public class ObjectProperties put(Property.PASSIVE, passive); put(Property.OWNER, owner); } - + public ObjectProperties(Boolean exclusive, Boolean noAck, Boolean noLocal, Boolean nowait, AMQQueue queue) { this(queue); @@ -230,17 +236,7 @@ public class ObjectProperties put(Property.EXCLUSIVE, exclusive); put(Property.NO_WAIT, nowait); } - - public List<String> getPropertyNames() - { - List<String> properties = new ArrayList<String>(); - for (Property property : _properties.keySet()) - { - properties.add(property.getName()); - } - return properties; - } - + public Boolean isSet(Property key) { return _properties.containsKey(key) && Boolean.valueOf(_properties.get(key)); @@ -255,17 +251,17 @@ public class ObjectProperties { return _properties.get(Property.NAME); } - + public void setName(String name) { _properties.put(Property.NAME, name); } - + public void setName(AMQShortString name) { put(Property.NAME, name); } - + public String put(Property key, AMQShortString value) { return put(key, value == null ? "" : value.asString()); @@ -275,7 +271,7 @@ public class ObjectProperties { return _properties.put(key, value == null ? "" : value.trim()); } - + public void put(Property key, Boolean value) { if (value != null) @@ -283,66 +279,64 @@ public class ObjectProperties _properties.put(key, Boolean.toString(value)); } } - + public boolean matches(ObjectProperties properties) { if (properties._properties.keySet().isEmpty()) { return true; } - + if (!_properties.keySet().containsAll(properties._properties.keySet())) { return false; } - + for (Map.Entry<Property,String> entry : properties._properties.entrySet()) { Property key = entry.getKey(); String ruleValue = entry.getValue(); - + String thisValue = _properties.get(key); - if (!valueMatches(thisValue, ruleValue)) + if (!valueMatches(thisValue, ruleValue)) { return false; } } - + return true; } - + private boolean valueMatches(String thisValue, String ruleValue) { return (StringUtils.isEmpty(ruleValue) || StringUtils.equals(thisValue, ruleValue)) || ruleValue.equals(STAR) - || (ruleValue.endsWith(STAR) + || (ruleValue.endsWith(STAR) && thisValue != null && thisValue.length() >= ruleValue.length() - 1 && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 1))); } @Override - public boolean equals(Object o) + public boolean equals(Object obj) { - if (this == o) + if (obj == null) { - return true; + return false; } - if (o == null || getClass() != o.getClass()) + if (obj == this) { - return false; + return true; } - - ObjectProperties that = (ObjectProperties) o; - - if (_properties != null ? !_properties.equals(that._properties) : that._properties != null) + if (obj.getClass() != getClass()) { return false; } - - return true; + ObjectProperties rhs = (ObjectProperties) obj; + return new EqualsBuilder() + .append(_properties, rhs._properties).isEquals(); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java index 90ecd1dd17..8bc4b9d278 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java @@ -41,12 +41,15 @@ public enum ObjectType { ALL(Operation.ALL), VIRTUALHOST(Operation.ALL, ACCESS), + MANAGEMENT(Operation.ALL, ACCESS), QUEUE(Operation.ALL, CREATE, DELETE, PURGE, CONSUME), EXCHANGE(Operation.ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH), LINK, // Not allowed in the Java broker ROUTE, // Not allowed in the Java broker - METHOD(Operation.ALL, ACCESS, UPDATE); - + METHOD(Operation.ALL, ACCESS, UPDATE), + USER(Operation.ALL, CREATE, DELETE, UPDATE), + GROUP(Operation.ALL, CREATE, DELETE, UPDATE); + private EnumSet<Operation> _actions; private ObjectType() diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java deleted file mode 100644 index 4df135a4ca..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security.access.plugins; - -import org.apache.qpid.server.security.AbstractPlugin; -import org.apache.qpid.server.security.Result; -import org.apache.qpid.server.security.access.ObjectProperties; -import org.apache.qpid.server.security.access.ObjectType; -import org.apache.qpid.server.security.access.Operation; - -/** - * This {@link org.apache.qpid.server.security.SecurityPlugin} simply abstains from all authorisation requests and ignores configuration. - */ -public abstract class BasicPlugin extends AbstractPlugin -{ - public Result access(ObjectType objectType, Object instance) - { - return getDefault(); - } - - public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties) - { - return getDefault(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java deleted file mode 100644 index 4b7a2fb457..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.qpid.server.security.access.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; -import org.apache.qpid.server.security.SecurityPluginFactory; - -import java.util.Arrays; -import java.util.List; - -/** - * The <code>LegacyAccess</code> plugin is used internally and simply ignores legacy elements of the configuration file. - */ -public class LegacyAccess extends BasicPlugin -{ - public static class LegacyAccessConfiguration extends ConfigurationPlugin { - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.msg-auth", "virtualhosts.virtualhost.security.msg-auth"); - } - - public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException - { - ConfigurationPlugin instance = new LegacyAccessConfiguration(); - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] { "" }; - } - } - - public static final SecurityPluginFactory<LegacyAccess> FACTORY = new SecurityPluginFactory<LegacyAccess>() - { - public LegacyAccess newInstance(ConfigurationPlugin config) throws ConfigurationException - { - LegacyAccessConfiguration configuration = config.getConfiguration(LegacyAccessConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - return null; - } - - LegacyAccess plugin = new LegacyAccess(); - plugin.configure(configuration); - return plugin; - } - - public String getPluginName() - { - return LegacyAccess.class.getName(); - } - - public Class<LegacyAccess> getPluginClass() - { - return LegacyAccess.class; - } - }; - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java new file mode 100644 index 0000000000..fb31132514 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticatedPrincipal.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.auth; + +import java.io.Serializable; +import java.security.Principal; +import java.util.Set; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.auth.UsernamePrincipal; + +/** + * A simple Principal wrapper. Exists to allow us to identify the "primary" principal + * by calling {@link Subject#getPrincipals(Class)}, passing in {@link AuthenticatedPrincipal}.class, + * e.g. when logging. + */ +public final class AuthenticatedPrincipal implements Principal, Serializable +{ + private final Principal _wrappedPrincipal; + + /** convenience constructor for the common case where we're wrapping a {@link UsernamePrincipal} */ + public AuthenticatedPrincipal(String userPrincipalName) + { + this(new UsernamePrincipal(userPrincipalName)); + } + + public AuthenticatedPrincipal(Principal wrappedPrincipal) + { + if(wrappedPrincipal == null) + { + throw new IllegalArgumentException("Wrapped principal is null"); + } + + _wrappedPrincipal = wrappedPrincipal; + } + + @Override + public String getName() + { + return _wrappedPrincipal.getName(); + } + + @Override + public int hashCode() + { + return _wrappedPrincipal.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + + if (!(obj instanceof AuthenticatedPrincipal)) + { + return false; + } + + AuthenticatedPrincipal other = (AuthenticatedPrincipal) obj; + + return _wrappedPrincipal.equals(other._wrappedPrincipal); + } + + public static AuthenticatedPrincipal getOptionalAuthenticatedPrincipalFromSubject(final Subject authSubject) + { + return getAuthenticatedPrincipalFromSubject(authSubject, true); + } + + public static AuthenticatedPrincipal getAuthenticatedPrincipalFromSubject(final Subject authSubject) + { + return getAuthenticatedPrincipalFromSubject(authSubject, false); + } + + private static AuthenticatedPrincipal getAuthenticatedPrincipalFromSubject(final Subject authSubject, boolean isPrincipalOptional) + { + if (authSubject == null) + { + throw new IllegalArgumentException("No authenticated subject."); + } + + final Set<AuthenticatedPrincipal> principals = authSubject.getPrincipals(AuthenticatedPrincipal.class); + int numberOfAuthenticatedPrincipals = principals.size(); + + if(numberOfAuthenticatedPrincipals == 0 && isPrincipalOptional) + { + return null; + } + else + { + if (numberOfAuthenticatedPrincipals != 1) + { + throw new IllegalArgumentException( + "Can't find single AuthenticatedPrincipal in authenticated subject. There were " + + numberOfAuthenticatedPrincipals + + " authenticated principals out of a total number of principals of: " + authSubject.getPrincipals()); + } + return principals.iterator().next(); + } + } + + @Override + public String toString() + { + return getName(); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java index 949c0f2b89..09bf6cf3b1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -20,15 +20,20 @@ */ package org.apache.qpid.server.security.auth; -import javax.security.auth.Subject; +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; /** - * Encapsulates the result of an attempt to authenticate. + * Encapsulates the result of an attempt to authenticate using an {@link AuthenticationManager}. * <p> * The authentication status describes the overall outcome. * <p> * <ol> - * <li>If authentication status is SUCCESS, the subject will be populated. + * <li>If authentication status is SUCCESS, at least one {@link Principal} will be populated. * </li> * <li>If authentication status is CONTINUE, the authentication has failed because the user * supplied incorrect credentials (etc). If the authentication requires it, the next challenge @@ -40,6 +45,8 @@ import javax.security.auth.Subject; * </li> * </ol> * + * The main principal provided to the constructor is wrapped in an {@link AuthenticatedPrincipal} + * to make it easier for the rest of the application to identify it among the set of other principals. */ public class AuthenticationResult { @@ -56,37 +63,59 @@ public class AuthenticationResult private final AuthenticationStatus _status; private final byte[] _challenge; private final Exception _cause; - private final Subject _subject; + private final Set<Principal> _principals = new HashSet<Principal>(); + private final Principal _mainPrincipal; public AuthenticationResult(final AuthenticationStatus status) { this(null, status, null); } + public AuthenticationResult(Principal mainPrincipal) + { + this(mainPrincipal, Collections.<Principal>emptySet()); + } + + public AuthenticationResult(Principal mainPrincipal, Set<Principal> otherPrincipals) + { + AuthenticatedPrincipal specialQpidAuthenticatedPrincipal = new AuthenticatedPrincipal(mainPrincipal); + _principals.addAll(otherPrincipals); + _principals.remove(mainPrincipal); + _principals.add(specialQpidAuthenticatedPrincipal); + _mainPrincipal = mainPrincipal; + + _status = AuthenticationStatus.SUCCESS; + _challenge = null; + _cause = null; + } + public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status) { - this(challenge, status, null); + _challenge = challenge; + _status = status; + _cause = null; + _mainPrincipal = null; } public AuthenticationResult(final AuthenticationStatus error, final Exception cause) { - this(null, error, cause); + _status = error; + _challenge = null; + _cause = cause; + _mainPrincipal = null; } public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status, final Exception cause) { - this._status = status; - this._challenge = challenge; - this._cause = cause; - this._subject = null; - } + if(status == AuthenticationStatus.SUCCESS) + { + throw new IllegalArgumentException("Successful authentication requires at least one principal"); + } - public AuthenticationResult(final Subject subject) - { - this._status = AuthenticationStatus.SUCCESS; - this._challenge = null; - this._cause = null; - this._subject = subject; + _status = status; + _challenge = challenge; + _cause = cause; + _mainPrincipal = null; } public Exception getCause() @@ -104,9 +133,13 @@ public class AuthenticationResult return _challenge; } - public Subject getSubject() + public Set<Principal> getPrincipals() { - return _subject; + return _principals; } + public Principal getMainPrincipal() + { + return _mainPrincipal; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java new file mode 100644 index 0000000000..3be96b87eb --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SubjectAuthenticationResult.java @@ -0,0 +1,76 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth; + +import java.security.Principal; + +import javax.security.auth.Subject; + +import org.apache.qpid.server.security.SubjectCreator; + +/** + * Encapsulates the result of an attempt to authenticate using a {@link SubjectCreator}. + * + * <p> + * iff authentication was successful, {@link #getSubject()} will return a non-null value and + * {@link #getStatus()} will return {@link AuthenticationResult.AuthenticationStatus#SUCCESS}. + * + * In this case, the {@link Subject} will contain the user {@link Principal} and zero or more other principals + * representing groups. + * </p> + * @see SubjectCreator + */ +public class SubjectAuthenticationResult +{ + private final AuthenticationResult _authenticationResult; + private final Subject _subject; + + public SubjectAuthenticationResult(AuthenticationResult authenticationResult, Subject subject) + { + _authenticationResult = authenticationResult; + _subject = subject; + } + + public SubjectAuthenticationResult(AuthenticationResult unsuccessfulAuthenticationResult) + { + this(unsuccessfulAuthenticationResult, null); + } + + public Exception getCause() + { + return _authenticationResult.getCause(); + } + + public AuthenticationResult.AuthenticationStatus getStatus() + { + return _authenticationResult.getStatus(); + } + + public byte[] getChallenge() + { + return _authenticationResult.getChallenge(); + } + + public Subject getSubject() + { + return _subject; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java index 9e7db94216..5b3c1d59cf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,14 +18,13 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.auth; -import javax.security.auth.Subject; +import java.io.Serializable; import java.security.Principal; -import java.util.Set; /** A principal that is just a wrapper for a simple username. */ -public class UsernamePrincipal implements Principal +public class UsernamePrincipal implements Principal, Serializable { private final String _name; @@ -48,9 +47,6 @@ public class UsernamePrincipal implements Principal return _name; } - /** - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { @@ -58,9 +54,6 @@ public class UsernamePrincipal implements Principal return prime * _name.hashCode(); } - /** - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(Object obj) { @@ -81,19 +74,4 @@ public class UsernamePrincipal implements Principal } } } - - public static UsernamePrincipal getUsernamePrincipalFromSubject(final Subject authSubject) - { - if (authSubject == null) - { - throw new IllegalArgumentException("No authenticated subject."); - } - - final Set<UsernamePrincipal> principals = authSubject.getPrincipals(UsernamePrincipal.class); - if (principals.size() != 1) - { - throw new IllegalArgumentException("Can't find single UsernamePrincipal in authenticated subject"); - } - return principals.iterator().next(); - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java index cac60a5283..578bb96efa 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.security.auth.database; import org.apache.log4j.Logger; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java index 67f4b7344a..605d2d019d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java @@ -32,6 +32,8 @@ import java.util.Map; /** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */ public interface PrincipalDatabase { + void setPasswordFile(String passwordFile) throws IOException; + /** * Set the password for a given principal in the specified callback. This is used for certain SASL providers. The * user database implementation should look up the password in any way it chooses and set it in the callback by diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java deleted file mode 100644 index 4203cb0e07..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.server.security.auth.database; - -import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; -import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser; -import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser; - -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.login.AccountNotFoundException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.security.Principal; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -public class PropertiesPrincipalDatabase implements PrincipalDatabase -{ - private Properties _users; - - private Map<String, AuthenticationProviderInitialiser> _saslServers; - - public PropertiesPrincipalDatabase(Properties users) - { - _users = users; - - _saslServers = new HashMap<String, AuthenticationProviderInitialiser>(); - - /** - * Create Authenticators for Properties Principal Database. - */ - - // Accept MD5 incomming and use plain comparison with the file - PlainInitialiser cram = new PlainInitialiser(); - cram.initialise(this); - // Accept Plain incomming and hash it for comparison to the file. - CRAMMD5Initialiser plain = new CRAMMD5Initialiser(); - plain.initialise(this, CRAMMD5Initialiser.HashDirection.INCOMMING); - - _saslServers.put(plain.getMechanismName(), cram); - _saslServers.put(cram.getMechanismName(), plain); - } - - public void setPassword(Principal principal, PasswordCallback callback) throws IOException, AccountNotFoundException - { - if (principal == null) - { - throw new IllegalArgumentException("principal must not be null"); - } - - - - final String pwd = _users.getProperty(principal.getName()); - - if (pwd != null) - { - callback.setPassword(pwd.toCharArray()); - } - else - { - throw new AccountNotFoundException("No account found for principal " + principal); - } - } - - public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException - { - //fixme this is not correct as toCharArray is not safe based on the type of string. - char[] pwd = _users.getProperty(principal).toCharArray(); - - return compareCharArray(pwd, password); - } - - public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException - { - return false; // updates denied - } - - public boolean createPrincipal(Principal principal, char[] password) - { - return false; // updates denied - } - - public boolean deletePrincipal(Principal principal) throws AccountNotFoundException - { - return false; // updates denied - } - - 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; - } - - private char[] convertPassword(String password) throws UnsupportedEncodingException - { - byte[] passwdBytes = password.getBytes("utf-8"); - - char[] passwd = new char[passwdBytes.length]; - - int index = 0; - - for (byte b : passwdBytes) - { - passwd[index++] = (char) b; - } - - return passwd; - } - - - public Map<String, AuthenticationProviderInitialiser> getMechanisms() - { - return _saslServers; - } - - public List<Principal> getUsers() - { - return new LinkedList<Principal>(); //todo - } - - public Principal getUser(String username) - { - if (_users.getProperty(username) != null) - { - return new UsernamePrincipal(username); - } - else - { - return null; - } - } - - public void reload() throws IOException - { - //No file to update from, so do nothing. - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java new file mode 100644 index 0000000000..ff21d63c87 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.io.IOException; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; + +/** + * Factory for {@link PrincipalDatabaseAuthenticationManager} objects configured + * with either the Plain or Base64MD5 digest {@link PrincipalDatabase} + * implementation. + */ +public abstract class AbstractPrincipalDatabaseAuthManagerFactory implements AuthenticationManagerFactory +{ + public static final String ATTRIBUTE_PATH = "path"; + + private static final Logger LOGGER = Logger.getLogger(AbstractPrincipalDatabaseAuthManagerFactory.class); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes == null || !getType().equals(attributes.get(ATTRIBUTE_TYPE))) + { + return null; + } + + String passwordFile = (String) attributes.get(ATTRIBUTE_PATH); + if (passwordFile == null) + { + LOGGER.warn("Password file path must not be null"); + return null; + } + + PrincipalDatabase principalDatabase = createPrincipalDatabase(); + try + { + principalDatabase.setPasswordFile(passwordFile); + } + catch (IOException e) + { + throw new RuntimeException(e.getMessage(), e); + } + + return new PrincipalDatabaseAuthenticationManager(principalDatabase); + } + + abstract String getType(); + + abstract PrincipalDatabase createPrincipalDatabase(); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java index 5676c43754..dd4c2e717a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java @@ -21,31 +21,25 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import java.util.Arrays; -import java.util.List; + import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousInitialiser; import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousSaslServer; public class AnonymousAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(AnonymousAuthenticationManager.class); - private static final AnonymousInitialiser SASL_INITIALISER = new AnonymousInitialiser(); private static final String ANONYMOUS = SASL_INITIALISER.getMechanismName(); - private static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal("ANONYMOUS"); + public static final String ANONYMOUS_USERNAME = "ANONYMOUS"; + + public static final Principal ANONYMOUS_PRINCIPAL = new UsernamePrincipal(ANONYMOUS_USERNAME); public static final Subject ANONYMOUS_SUBJECT = new Subject(); static @@ -53,76 +47,11 @@ public class AnonymousAuthenticationManager implements AuthenticationManager ANONYMOUS_SUBJECT.getPrincipals().add(ANONYMOUS_PRINCIPAL); } - private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_SUBJECT); - - - private static CallbackHandler _callbackHandler = SASL_INITIALISER.getCallbackHandler(); + private static final AuthenticationResult ANONYMOUS_AUTHENTICATION = new AuthenticationResult(ANONYMOUS_PRINCIPAL); static final AnonymousAuthenticationManager INSTANCE = new AnonymousAuthenticationManager(); - public static class AnonymousAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.anonymous-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new AnonymousAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<AnonymousAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<AnonymousAuthenticationManager>() - { - public AnonymousAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - AnonymousAuthenticationManagerConfiguration configuration = - config == null - ? null - : (AnonymousAuthenticationManagerConfiguration) config.getConfiguration(AnonymousAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for AnonymousAuthenticationManager"); - return null; - } - return INSTANCE; - } - - public Class<AnonymousAuthenticationManager> getPluginClass() - { - return AnonymousAuthenticationManager.class; - } - - public String getPluginName() - { - return AnonymousAuthenticationManager.class.getName(); - } - }; - - - private AnonymousAuthenticationManager() + AnonymousAuthenticationManager() { } @@ -184,9 +113,4 @@ public class AnonymousAuthenticationManager implements AuthenticationManager public void close() { } - - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java new file mode 100644 index 0000000000..1b1995500c --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class AnonymousAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = AnonymousAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new AnonymousAuthenticationManager(); + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java index ccddcb7669..c1a694f148 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java @@ -24,22 +24,22 @@ import java.security.Principal; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.auth.AuthenticationResult; /** * Implementations of the AuthenticationManager are responsible for determining * the authenticity of a user's credentials. - * - * If the authentication is successful, the manager is responsible for producing a populated - * {@link javax.security.auth.Subject} containing the user's identity and zero or more principals representing - * groups to which the user belongs. + * <p> + * If the authentication is successful, the manager is responsible for producing an + * {@link AuthenticationResult} containing the user's main {@link Principal} and zero or + * more other implementation-specific principals. + * </p> * <p> * The {@link #initialise()} method is responsible for registering SASL mechanisms required by * the manager. The {@link #close()} method must reverse this registration. - * + * </p> */ -public interface AuthenticationManager extends Closeable, Plugin +public interface AuthenticationManager extends Closeable { /** The name for the required SASL Server mechanisms */ public static final String PROVIDER_NAME= "AMQSASLProvider-Server"; @@ -88,5 +88,4 @@ public interface AuthenticationManager extends Closeable, Plugin * @return authentication result */ AuthenticationResult authenticate(String username, String password); - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java deleted file mode 100644 index 89a4d8ae66..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerRegistry.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security.auth.manager; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.configuration.ServerConfiguration; -import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.plugins.PluginManager; -import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration; - -/** - * A concrete implementation of {@link IAuthenticationManagerRegistry} that registers all {@link AuthenticationManager} - * instances defined in the configuration, building an optional mapping between port number and AuthenticationManager. - * - * <p>The default AuthenticationManager is either the one nominated as default within the configuration with - * {@link ServerConfiguration#getDefaultAuthenticationManager()}, or if there is only one, it is implicitly - * the default.</p> - * - * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers - * to reverse any security registrations they have performed.</p> - */ -public class AuthenticationManagerRegistry implements Closeable, IAuthenticationManagerRegistry -{ - private final Map<String,AuthenticationManager> _classToAuthManagerMap = new HashMap<String,AuthenticationManager>(); - private final AuthenticationManager _defaultAuthenticationManager; - private final Map<Integer,AuthenticationManager> _portToAuthenticationManagerMap; - private final List<RegistryChangeListener> _listeners = - Collections.synchronizedList(new ArrayList<RegistryChangeListener>()); - - public AuthenticationManagerRegistry(ServerConfiguration serverConfiguration, PluginManager _pluginManager) - throws ConfigurationException - { - final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values(); - - if (factories.size() == 0) - { - throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" + - " manager plugin has been placed in the plugins directory."); - } - - final SecurityConfiguration securityConfiguration = serverConfiguration.getConfiguration(SecurityConfiguration.class.getName()); - - boolean willClose = true; - try - { - createAuthenticationManagersRejectingDuplicates(factories, securityConfiguration); - - if(_classToAuthManagerMap.isEmpty()) - { - throw new ConfigurationException("No authentication managers configured within the configuration file."); - } - - _defaultAuthenticationManager = getDefaultAuthenticationManager(serverConfiguration); - - _portToAuthenticationManagerMap = getPortToAuthenticationManagerMap(serverConfiguration); - willClose = false; - } - finally - { - // if anything went wrong whilst configuring the registry, try to close all the AuthentcationManagers instantiated so far. - // This is done to allow the AuthenticationManager to undo any security registrations that they have performed. - if (willClose) - { - close(); - } - } - } - - @Override - public AuthenticationManager getAuthenticationManager(SocketAddress address) - { - AuthenticationManager authManager = - address instanceof InetSocketAddress - ? _portToAuthenticationManagerMap.get(((InetSocketAddress)address).getPort()) - : null; - - return authManager == null ? _defaultAuthenticationManager : authManager; - } - - @Override - public void close() - { - for (AuthenticationManager authManager : _classToAuthManagerMap.values()) - { - authManager.close(); - } - } - - private void createAuthenticationManagersRejectingDuplicates( - final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories, - final SecurityConfiguration securityConfiguration) - throws ConfigurationException - { - for(AuthenticationManagerPluginFactory<? extends Plugin> factory : factories) - { - final AuthenticationManager tmp = factory.newInstance(securityConfiguration); - if (tmp != null) - { - if(_classToAuthManagerMap.containsKey(tmp.getClass().getSimpleName())) - { - throw new ConfigurationException("Cannot configure more than one authentication manager of type " - + tmp.getClass().getSimpleName() + "." - + " Remove configuration for one of the authentication managers."); - } - _classToAuthManagerMap.put(tmp.getClass().getSimpleName(),tmp); - - for(RegistryChangeListener listener : _listeners) - { - listener.authenticationManagerRegistered(tmp); - } - } - } - } - - private AuthenticationManager getDefaultAuthenticationManager( - ServerConfiguration serverConfiguration) - throws ConfigurationException - { - final AuthenticationManager defaultAuthenticationManager; - if(_classToAuthManagerMap.size() == 1) - { - defaultAuthenticationManager = _classToAuthManagerMap.values().iterator().next(); - } - else if(serverConfiguration.getDefaultAuthenticationManager() != null) - { - defaultAuthenticationManager = _classToAuthManagerMap.get(serverConfiguration.getDefaultAuthenticationManager()); - if(defaultAuthenticationManager == null) - { - throw new ConfigurationException("No authentication managers configured of type " - + serverConfiguration.getDefaultAuthenticationManager() - + " which is specified as the default. Available managers are: " - + _classToAuthManagerMap.keySet()); - } - } - else - { - throw new ConfigurationException("If more than one authentication manager is configured a default MUST be specified."); - } - return defaultAuthenticationManager; - } - - private Map<Integer,AuthenticationManager> getPortToAuthenticationManagerMap( - ServerConfiguration serverConfiguration) - throws ConfigurationException - { - Map<Integer,AuthenticationManager> portToAuthenticationManagerMap = new HashMap<Integer, AuthenticationManager>(); - - for(Map.Entry<Integer,String> portMapping : serverConfiguration.getPortAuthenticationMappings().entrySet()) - { - - AuthenticationManager authenticationManager = _classToAuthManagerMap.get(portMapping.getValue()); - if(authenticationManager == null) - { - throw new ConfigurationException("Unknown authentication manager class " + portMapping.getValue() + - " configured for port " + portMapping.getKey()); - } - portToAuthenticationManagerMap.put(portMapping.getKey(), authenticationManager); - } - - return portToAuthenticationManagerMap; - } - - @Override - public Map<String, AuthenticationManager> getAvailableAuthenticationManagers() - { - return Collections.unmodifiableMap(new HashMap<String, AuthenticationManager>(_classToAuthManagerMap)); - } - - @Override - public void addRegistryChangeListener(RegistryChangeListener listener) - { - _listeners.add(listener); - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java index fefdecb8d7..c61567ef77 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFObjectClass.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactory.java @@ -18,27 +18,25 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.security.auth.manager; -import java.util.List; +import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -public abstract class QMFObjectClass<T extends QMFObject, S extends QMFObject.Delegate> extends QMFClass +public class Base64MD5PasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory { - public QMFObjectClass(String name, - byte[] schemaHash, - List<QMFProperty> properties, - List<QMFStatistic> statistics, List<QMFMethod> methods) + public static final String PROVIDER_TYPE = "Base64MD5PasswordFileAuthenticationProvider"; + + @Override + String getType() { - super(QMFClass.Type.OBJECT, name, schemaHash, properties, statistics, methods); + return PROVIDER_TYPE; } - public QMFObjectClass(String name, byte[] schemaHash) + @Override + PrincipalDatabase createPrincipalDatabase() { - super(QMFClass.Type.OBJECT, name, schemaHash); + return new Base64MD5PasswordFilePrincipalDatabase(); } - - public abstract T newInstance(S delegate); - - } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java index 2d6866b657..9ed8cf7fed 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManager.java @@ -19,90 +19,19 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import java.util.Arrays; -import java.util.List; -import javax.security.auth.Subject; + import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.external.ExternalSaslServer; public class ExternalAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(ExternalAuthenticationManager.class); - private static final String EXTERNAL = "EXTERNAL"; - static final ExternalAuthenticationManager INSTANCE = new ExternalAuthenticationManager(); - - public static class ExternalAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.external-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new ExternalAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<ExternalAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<ExternalAuthenticationManager>() - { - public ExternalAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - ExternalAuthenticationManagerConfiguration configuration = - config == null - ? null - : (ExternalAuthenticationManagerConfiguration) config.getConfiguration(ExternalAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for ExternalAuthenticationManager"); - return null; - } - return INSTANCE; - } - - public Class<ExternalAuthenticationManager> getPluginClass() - { - return ExternalAuthenticationManager.class; - } - - public String getPluginName() - { - return ExternalAuthenticationManager.class.getName(); - } - }; - - - private ExternalAuthenticationManager() + ExternalAuthenticationManager() { } @@ -137,15 +66,13 @@ public class ExternalAuthenticationManager implements AuthenticationManager // Process response from the client try { - byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]); + server.evaluateResponse(response != null ? response : new byte[0]); Principal principal = ((ExternalSaslServer)server).getAuthenticatedPrincipal(); if(principal != null) { - final Subject subject = new Subject(); - subject.getPrincipals().add(principal); - return new AuthenticationResult(subject); + return new AuthenticationResult(principal); } else { @@ -162,16 +89,11 @@ public class ExternalAuthenticationManager implements AuthenticationManager @Override public AuthenticationResult authenticate(String username, String password) { - return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR); + return new AuthenticationResult(new UsernamePrincipal(username)); } @Override public void close() { } - - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java index b101d70553..3c3628e9db 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SubscriptionConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java @@ -1,5 +1,4 @@ /* - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -18,30 +17,24 @@ * under the License. * */ - -package org.apache.qpid.server.configuration; +package org.apache.qpid.server.security.auth.manager; import java.util.Map; +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; -public interface SubscriptionConfig extends ConfiguredObject<SubscriptionConfigType, SubscriptionConfig> +public class ExternalAuthenticationManagerFactory implements AuthenticationManagerFactory { - - SessionConfig getSessionConfig(); - - QueueConfig getQueue(); - - String getName(); - - Map<String, Object> getArguments(); - - String getCreditMode(); - - boolean isBrowsing(); - - boolean isExclusive(); - - boolean isExplicitAcknowledge(); - - Long getDelivered(); -}
\ No newline at end of file + public static final String PROVIDER_TYPE = ExternalAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new ExternalAuthenticationManager(); + } + return null; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java deleted file mode 100644 index 485ca2e1e9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/IAuthenticationManagerRegistry.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.security.auth.manager; - -import java.net.SocketAddress; - -import java.util.Map; -import org.apache.qpid.common.Closeable; -import org.apache.qpid.server.virtualhost.VirtualHost; - -/** - * Registry for {@link AuthenticationManager} instances. - * - * <p>A lookup method {@link #getAuthenticationManager(SocketAddress)} allows a caller to determine - * the AuthenticationManager associated with a particular port number.</p> - * - * <p>It is important to {@link #close()} the registry after use and this allows the AuthenticationManagers - * to reverse any security registrations they have performed.</p> - */ -public interface IAuthenticationManagerRegistry extends Closeable -{ - /** - * Returns the {@link AuthenticationManager} associated with a particular {@link SocketAddress}. - * If no authentication manager is associated with this address, a default authentication manager will be - * returned. Null is never returned. - * - * @param address - * @return authentication manager. - */ - public AuthenticationManager getAuthenticationManager(SocketAddress address); - - Map<String, AuthenticationManager> getAvailableAuthenticationManagers(); - - public static interface RegistryChangeListener - { - void authenticationManagerRegistered(AuthenticationManager authenticationManager); - void authenticationManagerUnregistered(AuthenticationManager authenticationManager); - } - - public void addRegistryChangeListener(RegistryChangeListener listener); - -}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java index d735ecb1d4..3c1b709648 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java @@ -20,10 +20,7 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; -import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; @@ -31,86 +28,15 @@ import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; public class KerberosAuthenticationManager implements AuthenticationManager { - private static final Logger _logger = Logger.getLogger(KerberosAuthenticationManager.class); - private static final String GSSAPI_MECHANISM = "GSSAPI"; private final CallbackHandler _callbackHandler = new GssApiCallbackHandler(); - public static class KerberosAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.kerberos-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new KerberosAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[0]; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - } - - - public static final AuthenticationManagerPluginFactory<KerberosAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<KerberosAuthenticationManager>() - { - public KerberosAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - KerberosAuthenticationManagerConfiguration configuration = - config == null - ? null - : (KerberosAuthenticationManagerConfiguration) config.getConfiguration(KerberosAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for KerberosAuthenticationManager"); - return null; - } - KerberosAuthenticationManager kerberosAuthenticationManager = new KerberosAuthenticationManager(); - kerberosAuthenticationManager.configure(configuration); - return kerberosAuthenticationManager; - } - - public Class<KerberosAuthenticationManager> getPluginClass() - { - return KerberosAuthenticationManager.class; - } - - public String getPluginName() - { - return KerberosAuthenticationManager.class.getName(); - } - }; - - - private KerberosAuthenticationManager() + KerberosAuthenticationManager() { } @@ -158,10 +84,7 @@ public class KerberosAuthenticationManager implements AuthenticationManager if (server.isComplete()) { - final Subject subject = new Subject(); - _logger.debug("Authenticated as " + server.getAuthorizationID()); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID())); } else { @@ -186,11 +109,6 @@ public class KerberosAuthenticationManager implements AuthenticationManager { } - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException - { - } - private static class GssApiCallbackHandler implements CallbackHandler { diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java new file mode 100644 index 0000000000..7af6727280 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class KerberosAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + public static final String PROVIDER_TYPE = KerberosAuthenticationManager.class.getSimpleName(); + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return new KerberosAuthenticationManager(); + } + return null; + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java index a51f195761..43b92735f1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactory.java @@ -20,13 +20,23 @@ */ package org.apache.qpid.server.security.auth.manager; -import org.apache.qpid.server.plugins.PluginFactory; +import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase; +import org.apache.qpid.server.security.auth.database.PrincipalDatabase; -/** - * Factory producing authentication producing configured, initialised authentication - * managers. - */ -public interface AuthenticationManagerPluginFactory<S extends AuthenticationManager> extends PluginFactory<S> +public class PlainPasswordFileAuthenticationManagerFactory extends AbstractPrincipalDatabaseAuthManagerFactory { + public static final String PROVIDER_TYPE = "PlainPasswordFileAuthenticationProvider"; + + @Override + String getType() + { + return PROVIDER_TYPE; + } + + @Override + PrincipalDatabase createPrincipalDatabase() + { + return new PlainPasswordFilePrincipalDatabase(); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java index e6498919a1..f4c834810d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java @@ -21,38 +21,25 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.configuration.PropertyException; -import org.apache.qpid.configuration.PropertyUtils; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; import org.apache.qpid.server.security.auth.sasl.JCAProvider; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.UsernamePrincipal; -import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.AccountNotFoundException; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; + import java.security.Security; -import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.TreeMap; @@ -60,27 +47,10 @@ import java.util.TreeMap; * Concrete implementation of the AuthenticationManager that determines if supplied * user credentials match those appearing in a PrincipalDatabase. The implementation * of the PrincipalDatabase is determined from the configuration. - * - * This implementation also registers the JMX UserManagemement MBean. - * - * This plugin expects configuration such as: - * - * <pre> - * <pd-auth-manager> - * <principal-database> - * <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class> - * <attributes> - * <attribute> - * <name>passwordFile</name> - * <value>${conf}/passwd</value> - * </attribute> - * </attributes> - * </principal-database> - * </pd-auth-manager> - * </pre> */ public class PrincipalDatabaseAuthenticationManager implements AuthenticationManager { + private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class); /** The list of mechanisms, in the order in which they are configured (i.e. preferred order) */ @@ -95,95 +65,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan */ private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>(); - private PrincipalDatabase _principalDatabase = null; + private final PrincipalDatabase _principalDatabase; - public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>() - { - public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - final PrincipalDatabaseAuthenticationManagerConfiguration configuration = - config == null - ? null - : (PrincipalDatabaseAuthenticationManagerConfiguration) config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for PrincipalDatabaseAuthenticationManager"); - return null; - } - - final PrincipalDatabaseAuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager(); - pdam.configure(configuration); - pdam.initialise(); - return pdam; - } - - public Class<PrincipalDatabaseAuthenticationManager> getPluginClass() - { - return PrincipalDatabaseAuthenticationManager.class; - } - - public String getPluginName() - { - return PrincipalDatabaseAuthenticationManager.class.getName(); - } - }; - - public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin { - - public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.pd-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new PrincipalDatabaseAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - public String[] getElementsProcessed() - { - return new String[] {"principal-database.class", - "principal-database.attributes.attribute.name", - "principal-database.attributes.attribute.value"}; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - public String getPrincipalDatabaseClass() - { - return getConfig().getString("principal-database.class"); - } - - public Map<String,String> getPdClassAttributeMap() throws ConfigurationException - { - final List<String> argumentNames = (List) getConfig().getList("principal-database.attributes.attribute.name"); - final List<String> argumentValues = (List) getConfig().getList("principal-database.attributes.attribute.value"); - final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size()); - - for (int i = 0; i < argumentNames.size(); i++) - { - final String argName = argumentNames.get(i); - final String argValue = argumentValues.get(i); - - attributes.put(argName, argValue); - } - - return Collections.unmodifiableMap(attributes); - } - } - - protected PrincipalDatabaseAuthenticationManager() + public PrincipalDatabaseAuthenticationManager(PrincipalDatabase pd) { + _principalDatabase = pd; } public void initialise() @@ -246,21 +132,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan _logger.info("Initialised " + mechanism + " SASL provider successfully"); } - /** - * @see org.apache.qpid.server.plugins.Plugin#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin) - */ - public void configure(final ConfigurationPlugin config) throws ConfigurationException - { - final PrincipalDatabaseAuthenticationManagerConfiguration pdamConfig = (PrincipalDatabaseAuthenticationManagerConfiguration) config; - final String pdClazz = pdamConfig.getPrincipalDatabaseClass(); - - _logger.info("PrincipalDatabase concrete implementation : " + pdClazz); - - _principalDatabase = createPrincipalDatabaseImpl(pdClazz); - - configPrincipalDatabase(_principalDatabase, pdamConfig); - } - public String getMechanisms() { return _mechanisms; @@ -268,8 +139,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException { - return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism), - _callbackHandlerMap.get(mechanism)); + Map<String, ?> properties = _serverCreationProperties.get(mechanism); + CallbackHandler callbackHandler = _callbackHandlerMap.get(mechanism); + + return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, properties, + callbackHandler); } /** @@ -284,9 +158,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan if (server.isComplete()) { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + final String userId = server.getAuthorizationID(); + return new AuthenticationResult(new UsernamePrincipal(userId)); } else { @@ -308,9 +181,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan { if (_principalDatabase.verifyPassword(username, password.toCharArray())) { - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(username)); - return new AuthenticationResult(subject); + return new AuthenticationResult(new UsernamePrincipal(username)); } else { @@ -329,100 +200,8 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan Security.removeProvider(PROVIDER_NAME); } - private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException - { - try - { - return (PrincipalDatabase) Class.forName(pdClazz).newInstance(); - } - catch (InstantiationException ie) - { - throw new ConfigurationException("Cannot instantiate " + pdClazz, ie); - } - catch (IllegalAccessException iae) - { - throw new ConfigurationException("Cannot access " + pdClazz, iae); - } - catch (ClassNotFoundException cnfe) - { - throw new ConfigurationException("Cannot load " + pdClazz + " implementation", cnfe); - } - catch (ClassCastException cce) - { - throw new ConfigurationException("Expecting a " + PrincipalDatabase.class + " implementation", cce); - } - } - - private void configPrincipalDatabase(final PrincipalDatabase principalDatabase, final PrincipalDatabaseAuthenticationManagerConfiguration config) - throws ConfigurationException - { - - final Map<String,String> attributes = config.getPdClassAttributeMap(); - - for (Iterator<Entry<String, String>> iterator = attributes.entrySet().iterator(); iterator.hasNext();) - { - final Entry<String, String> nameValuePair = iterator.next(); - final String methodName = generateSetterName(nameValuePair.getKey()); - final Method method; - try - { - method = principalDatabase.getClass().getMethod(methodName, String.class); - } - catch (Exception e) - { - throw new ConfigurationException("No method " + methodName + " found in class " - + principalDatabase.getClass() - + " hence unable to configure principal database. The method must be public and " - + "have a single String argument with a void return type", e); - } - try - { - method.invoke(principalDatabase, PropertyUtils.replaceProperties(nameValuePair.getValue())); - } - catch (IllegalArgumentException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (PropertyException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (IllegalAccessException e) - { - throw new ConfigurationException(e.getMessage(), e); - } - catch (InvocationTargetException e) - { - // QPID-1347.. InvocationTargetException wraps the checked exception thrown from the reflective - // method call. Pull out the underlying message and cause to make these more apparent to the user. - throw new ConfigurationException(e.getCause().getMessage(), e.getCause()); - } - } - } - public PrincipalDatabase getPrincipalDatabase() { return _principalDatabase; } - - private String generateSetterName(String argName) throws ConfigurationException - { - if ((argName == null) || (argName.length() == 0)) - { - throw new ConfigurationException("Argument names must have length >= 1 character"); - } - - if (Character.isLowerCase(argName.charAt(0))) - { - argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1); - } - - final String methodName = "set" + argName; - return methodName; - } - - protected void setPrincipalDatabase(final PrincipalDatabase principalDatabase) - { - _principalDatabase = principalDatabase; - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java index 64b24e28bc..7891ef8cf5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java @@ -21,10 +21,10 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; -import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; -import java.util.List; + +import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -32,7 +32,6 @@ import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; -import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; @@ -41,13 +40,10 @@ import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; +import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback; public class SimpleLDAPAuthenticationManager implements AuthenticationManager @@ -55,123 +51,25 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManager.class); private static final String PLAIN_MECHANISM = "PLAIN"; - private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; - private String _providerSearchURL; - private String _searchContext; - private String _searchFilter; - private String _providerAuthURL; - private String _ldapContextFactory; - - public static class SimpleLDAPAuthenticationManagerConfiguration extends ConfigurationPlugin - { - - public static final ConfigurationPluginFactory FACTORY = - new ConfigurationPluginFactory() - { - public List<String> getParentPaths() - { - return Arrays.asList("security.simple-ldap-auth-manager"); - } - - public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException - { - final ConfigurationPlugin instance = new SimpleLDAPAuthenticationManagerConfiguration(); - - instance.setConfiguration(path, config); - return instance; - } - }; - - private static final String PROVIDER_URL = "provider-url"; - private static final String PROVIDER_SEARCH_URL = "provider-search-url"; - private static final String PROVIDER_AUTH_URL = "provider-auth-url"; - private static final String SEARCH_CONTEXT = "search-context"; - private static final String SEARCH_FILTER = "search-filter"; - private static final String LDAP_CONTEXT_FACTORY = "ldap-context-factory"; - - public String[] getElementsProcessed() - { - return new String[] {PROVIDER_URL, PROVIDER_SEARCH_URL, PROVIDER_AUTH_URL, SEARCH_CONTEXT, SEARCH_FILTER, - LDAP_CONTEXT_FACTORY}; - } - - public void validateConfiguration() throws ConfigurationException - { - } - - public String getLDAPContextFactory() - { - return getConfig().getString(LDAP_CONTEXT_FACTORY, DEFAULT_LDAP_CONTEXT_FACTORY); - } - - - public String getProviderURL() - { - return getConfig().getString(PROVIDER_URL); - } - - public String getProviderSearchURL() - { - return getConfig().getString(PROVIDER_SEARCH_URL, getProviderURL()); - } - - public String getSearchContext() - { - return getConfig().getString(SEARCH_CONTEXT); - } - - public String getSearchFilter() - { - return getConfig().getString(SEARCH_FILTER); - } - - public String getProviderAuthURL() - { - return getConfig().getString(PROVIDER_AUTH_URL, getProviderURL()); - } - } - - - public static final AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<SimpleLDAPAuthenticationManager>() - { - public SimpleLDAPAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException - { - SimpleLDAPAuthenticationManagerConfiguration configuration = - config == null - ? null - : (SimpleLDAPAuthenticationManagerConfiguration) config.getConfiguration(SimpleLDAPAuthenticationManagerConfiguration.class.getName()); - - // If there is no configuration for this plugin then don't load it. - if (configuration == null) - { - _logger.info("No authentication-manager configuration found for SimpleLDAPAuthenticationManager"); - return null; - } - SimpleLDAPAuthenticationManager simpleLDAPAuthenticationManager = new SimpleLDAPAuthenticationManager(); - simpleLDAPAuthenticationManager.configure(configuration); - return simpleLDAPAuthenticationManager; - } - - public Class<SimpleLDAPAuthenticationManager> getPluginClass() - { - return SimpleLDAPAuthenticationManager.class; - } - - public String getPluginName() - { - return SimpleLDAPAuthenticationManager.class.getName(); - } - }; - + private final String _providerSearchURL; + private final String _providerAuthURL; + private final String _searchContext; + private final String _searchFilter; + private final String _ldapContextFactory; - private SimpleLDAPAuthenticationManager() + SimpleLDAPAuthenticationManager(String providerSearchUrl, String providerAuthUrl, String searchContext, String searchFilter, String ldapContextFactory) { + _providerSearchURL = providerSearchUrl; + _providerAuthURL = providerAuthUrl; + _searchContext = searchContext; + _searchFilter = searchFilter; + _ldapContextFactory = ldapContextFactory; } @Override public void initialise() { - + validateInitialDirContext(); } @Override @@ -205,10 +103,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager if (server.isComplete()) { - final Subject subject = new Subject(); - _logger.debug("Authenticated as " + server.getAuthorizationID()); - subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID())); - return new AuthenticationResult(subject); + String authorizationID = server.getAuthorizationID(); + _logger.debug("Authenticated as " + authorizationID); + + return new AuthenticationResult(new UsernamePrincipal(authorizationID)); } else { @@ -224,34 +122,74 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager @Override public AuthenticationResult authenticate(String username, String password) { - try { - return doLDAPNameAuthentication(getNameFromId(username), password); + AuthenticationResult result = doLDAPNameAuthentication(getNameFromId(username), password); + if(result.getStatus() == AuthenticationStatus.SUCCESS) + { + //Return a result based on the supplied username rather than the search name + return new AuthenticationResult(new UsernamePrincipal(username)); + } + else + { + return result; + } } catch (NamingException e) { - return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); - } } - private AuthenticationResult doLDAPNameAuthentication(String username, String password) throws NamingException + private AuthenticationResult doLDAPNameAuthentication(String name, String password) { + if(name == null) + { + //The search didn't return anything, class as not-authenticated before it NPEs below + return new AuthenticationResult(AuthenticationStatus.CONTINUE); + } + Hashtable<Object,Object> env = new Hashtable<Object,Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerAuthURL); env.put(Context.SECURITY_AUTHENTICATION, "simple"); - env.put(Context.SECURITY_PRINCIPAL, username); + env.put(Context.SECURITY_PRINCIPAL, name); env.put(Context.SECURITY_CREDENTIALS, password); - DirContext ctx = new InitialDirContext(env); - ctx.close(); - final Subject subject = new Subject(); - subject.getPrincipals().add(new UsernamePrincipal(username)); - return new AuthenticationResult(subject); + + DirContext ctx = null; + try + { + ctx = new InitialDirContext(env); + + //Authentication succeeded + return new AuthenticationResult(new UsernamePrincipal(name)); + } + catch(AuthenticationException ae) + { + //Authentication failed + return new AuthenticationResult(AuthenticationStatus.CONTINUE); + } + catch (NamingException e) + { + //Some other failure + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + } + finally + { + if(ctx != null) + { + try + { + ctx.close(); + } + catch (Exception e) + { + _logger.warn("Exception closing InitialDirContext", e); + } + } + } } @Override @@ -259,17 +197,8 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager { } - @Override - public void configure(ConfigurationPlugin config) throws ConfigurationException + private void validateInitialDirContext() { - SimpleLDAPAuthenticationManagerConfiguration ldapConfig = (SimpleLDAPAuthenticationManagerConfiguration) config; - - _ldapContextFactory = ldapConfig.getLDAPContextFactory(); - _providerSearchURL = ldapConfig.getProviderSearchURL(); - _providerAuthURL = ldapConfig.getProviderAuthURL(); - _searchContext = ldapConfig.getSearchContext(); - _searchFilter = ldapConfig.getSearchFilter(); - Hashtable<String,Object> env = new Hashtable<String, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerSearchURL); @@ -277,11 +206,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager try { - new InitialDirContext(env); + new InitialDirContext(env).close(); } catch (NamingException e) { - throw new ConfigurationException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e); + throw new RuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e); } } @@ -305,19 +234,11 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager } catch (NamingException e) { - _logger.info("SASL Authentication Error", e); + _logger.warn("SASL Authentication Exception", e); } if(password != null) { - try - { - authenticated = doLDAPNameAuthentication(name, password); - - } - catch (NamingException e) - { - authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); - } + authenticated = doLDAPNameAuthentication(name, password); } } else if (callback instanceof PlainPasswordCallback) @@ -325,17 +246,10 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager password = ((PlainPasswordCallback)callback).getPlainPassword(); if(name != null) { - try - { - authenticated = doLDAPNameAuthentication(name, password); - if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS) - { - ((PlainPasswordCallback)callback).setAuthenticated(true); - } - } - catch (NamingException e) + authenticated = doLDAPNameAuthentication(name, password); + if(authenticated.getStatus()== AuthenticationResult.AuthenticationStatus.SUCCESS) { - authenticated = new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + ((PlainPasswordCallback)callback).setAuthenticated(true); } } } @@ -357,7 +271,6 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory); env.put(Context.PROVIDER_URL, _providerSearchURL); - env.put(Context.SECURITY_AUTHENTICATION, "none"); DirContext ctx = null; @@ -382,7 +295,14 @@ public class SimpleLDAPAuthenticationManager implements AuthenticationManager } finally { - ctx.close(); + try + { + ctx.close(); + } + catch (Exception e) + { + _logger.warn("Exception closing InitialDirContext", e); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java new file mode 100644 index 0000000000..05a692fb0e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.manager; + +import java.util.Map; + +import org.apache.qpid.server.plugin.AuthenticationManagerFactory; + +public class SimpleLDAPAuthenticationManagerFactory implements AuthenticationManagerFactory +{ + private static final String DEFAULT_LDAP_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory"; + + public static final String PROVIDER_TYPE = SimpleLDAPAuthenticationManager.class.getSimpleName(); + + public static final String ATTRIBUTE_LDAP_CONTEXT_FACTORY = "ldapContextFactory"; + public static final String ATTRIBUTE_SEARCH_FILTER = "searchFilter"; + public static final String ATTRIBUTE_SEARCH_CONTEXT = "searchContext"; + public static final String ATTRIBUTE_PROVIDER_AUTH_URL = "providerAuthUrl"; + public static final String ATTRIBUTE_PROVIDER_SEARCH_URL = "providerSearchUrl"; + public static final String ATTRIBUTE_PROVIDER_URL = "providerUrl"; + + @Override + public AuthenticationManager createInstance(Map<String, Object> attributes) + { + if (attributes == null || !PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE))) + { + return null; + } + String providerUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_URL); + String providerSearchUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_SEARCH_URL); + if (providerSearchUrl == null) + { + providerSearchUrl = providerUrl; + } + String providerAuthUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_AUTH_URL); + if (providerAuthUrl == null) + { + providerAuthUrl = providerUrl; + } + String searchContext = (String) attributes.get(ATTRIBUTE_SEARCH_CONTEXT); + String searchFilter = (String) attributes.get(ATTRIBUTE_SEARCH_FILTER); + String ldapContextFactory = (String) attributes.get(ATTRIBUTE_LDAP_CONTEXT_FACTORY); + if (ldapContextFactory == null) + { + ldapContextFactory = DEFAULT_LDAP_CONTEXT_FACTORY; + } + + return new SimpleLDAPAuthenticationManager(providerSearchUrl, providerAuthUrl, searchContext, searchFilter, + ldapContextFactory); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java index 2e21cfbb07..abb8677e90 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java @@ -22,13 +22,13 @@ package org.apache.qpid.server.security.auth.rmi; import java.net.SocketAddress; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import javax.management.remote.JMXAuthenticator; -import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; public class RMIPasswordAuthenticator implements JMXAuthenticator @@ -38,23 +38,33 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator static final String SHOULD_HAVE_2_ELEMENTS = "User details should have 2 elements, username, password"; static final String SHOULD_BE_NON_NULL = "Supplied username and password should be non-null"; static final String INVALID_CREDENTIALS = "Invalid user details supplied"; + static final String USER_NOT_AUTHORISED_FOR_MANAGEMENT = "User not authorised for management"; static final String CREDENTIALS_REQUIRED = "User details are required. " + - "Please ensure you are using an up to date management console to connect."; + "Please ensure you are using an up to date management console to connect."; - private AuthenticationManager _authenticationManager = null; - private SocketAddress _socketAddress; + private final Broker _broker; + private final SocketAddress _address; - public RMIPasswordAuthenticator(SocketAddress socketAddress) + public RMIPasswordAuthenticator(Broker broker, SocketAddress address) { - _socketAddress = socketAddress; + _broker = broker; + _address = address; } - public void setAuthenticationManager(final AuthenticationManager authenticationManager) + public Subject authenticate(Object credentials) throws SecurityException { - _authenticationManager = authenticationManager; + validateCredentials(credentials); + + final String[] userCredentials = (String[]) credentials; + final String username = (String) userCredentials[0]; + final String password = (String) userCredentials[1]; + + final Subject authenticatedSubject = doAuthentication(username, password); + doManagementAuthorisation(authenticatedSubject); + return authenticatedSubject; } - public Subject authenticate(Object credentials) throws SecurityException + private void validateCredentials(Object credentials) { // Verify that credential's are of type String[]. if (!(credentials instanceof String[])) @@ -70,41 +80,27 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator } // Verify that required number of credentials. - final String[] userCredentials = (String[]) credentials; - if (userCredentials.length != 2) + if (((String[])credentials).length != 2) { throw new SecurityException(SHOULD_HAVE_2_ELEMENTS); } + } - final String username = (String) userCredentials[0]; - final String password = (String) userCredentials[1]; - + private Subject doAuthentication(final String username, final String password) + { // Verify that all required credentials are actually present. if (username == null || password == null) { throw new SecurityException(SHOULD_BE_NON_NULL); } - // Verify that an AuthenticationManager has been set. - if (_authenticationManager == null) + SubjectCreator subjectCreator = _broker.getSubjectCreator(_address); + if (subjectCreator == null) { - try - { - if(ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress) != null) - { - _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager(_socketAddress); - } - else - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } - } - catch(IllegalStateException e) - { - throw new SecurityException(UNABLE_TO_LOOKUP); - } + throw new SecurityException("Can't get subject creator for " + _address); } - final AuthenticationResult result = _authenticationManager.authenticate(username, password); + + final SubjectAuthenticationResult result = subjectCreator.authenticate(username, password); if (AuthenticationStatus.ERROR.equals(result.getStatus())) { @@ -112,10 +108,7 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator } else if (AuthenticationStatus.SUCCESS.equals(result.getStatus())) { - final Subject subject = result.getSubject(); - subject.getPrincipals().add(new JMXPrincipal(username)); - subject.setReadOnly(); - return subject; + return result.getSubject(); } else { @@ -123,4 +116,21 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator } } + private void doManagementAuthorisation(Subject authenticatedSubject) + { + SecurityManager.setThreadSubject(authenticatedSubject); + try + { + if (!_broker.getSecurityManager().accessManagement()) + { + throw new SecurityException(USER_NOT_AUTHORISED_FOR_MANAGEMENT); + } + } + finally + { + SecurityManager.setThreadSubject(null); + } + } + + }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java index f4e8f800c6..b70a987107 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.security.auth.sasl; import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; +import org.apache.qpid.server.security.auth.UsernamePrincipal; import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import javax.security.auth.callback.Callback; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java index 52d36023c2..d10193e743 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServer.java @@ -23,6 +23,8 @@ package org.apache.qpid.server.security.auth.sasl.anonymous; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; +import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; + public class AnonymousSaslServer implements SaslServer { @@ -52,7 +54,7 @@ public class AnonymousSaslServer implements SaslServer public String getAuthorizationID() { - return null; + return AnonymousAuthenticationManager.ANONYMOUS_PRINCIPAL.getName(); } public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java index 478f195530..4e12ac0750 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java @@ -139,6 +139,12 @@ public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser { _realPricipalDatabase.reload(); } + + @Override + public void setPasswordFile(String passwordFile) throws IOException + { + throw new UnsupportedOperationException(); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java new file mode 100644 index 0000000000..c66e7fd4e4 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupDatabase.java @@ -0,0 +1,287 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.group; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Date; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +/** + * A group database that reads/writes the following file format: + * + * group1.users=user1,user2 + * group2.users=user2,user3 + */ +public class FileGroupDatabase implements GroupDatabase +{ + private static final Logger LOGGER = Logger.getLogger(FileGroupDatabase.class); + + private Map<String, Set<String>> _groupToUserMap = new ConcurrentHashMap<String, Set<String>>(); + private Map<String, Set<String>> _userToGroupMap = new ConcurrentHashMap<String, Set<String>>(); + private String _groupFile; + + @Override + public Set<String> getAllGroups() + { + return Collections.unmodifiableSet(_groupToUserMap.keySet()); + } + + public synchronized void setGroupFile(String groupFile) throws IOException + { + File file = new File(groupFile); + + if (!file.canRead()) + { + throw new FileNotFoundException(groupFile + + " cannot be found or is not readable"); + } + + readGroupFile(groupFile); + } + + @Override + public Set<String> getUsersInGroup(String group) + { + if (group == null) + { + LOGGER.warn("Requested user set for null group. Returning empty set."); + return Collections.emptySet(); + } + + Set<String> set = _groupToUserMap.get(group); + if (set == null) + { + return Collections.emptySet(); + } + else + { + return Collections.unmodifiableSet(set); + } + } + + @Override + public synchronized void addUserToGroup(String user, String group) + { + Set<String> users = _groupToUserMap.get(group); + if (users == null) + { + throw new IllegalArgumentException("Group " + group + " does not exist so could not add " + user + " to it"); + } + + users.add(user); + + Set<String> groups = _userToGroupMap.get(user); + if (groups == null) + { + groups = new ConcurrentSkipListSet<String>(); + _userToGroupMap.put(user, groups); + } + groups.add(group); + + update(); + } + + @Override + public synchronized void removeUserFromGroup(String user, String group) + { + Set<String> users = _groupToUserMap.get(group); + if (users == null) + { + throw new IllegalArgumentException("Group " + group + " does not exist so could not remove " + user + " from it"); + } + + users.remove(user); + + Set<String> groups = _userToGroupMap.get(user); + if (groups != null) + { + groups.remove(group); + } + + update(); + } + + @Override + public Set<String> getGroupsForUser(String user) + { + if(user == null) + { + LOGGER.warn("Requested group set for null user. Returning empty set."); + return Collections.emptySet(); + } + + Set<String> groups = _userToGroupMap.get(user); + if (groups == null) + { + return Collections.emptySet(); + } + else + { + return Collections.unmodifiableSet(groups); + } + } + + @Override + public synchronized void createGroup(String group) + { + Set<String> users = new ConcurrentSkipListSet<String>(); + _groupToUserMap.put(group, users); + + update(); + } + + @Override + public synchronized void removeGroup(String group) + { + _groupToUserMap.remove(group); + for (Set<String> groupsForUser : _userToGroupMap.values()) + { + groupsForUser.remove(group); + } + + update(); + } + + private synchronized void update() + { + if (_groupFile != null) + { + try + { + writeGroupFile(_groupFile); + } + catch (IOException e) + { + throw new RuntimeException("Unable to persist change to file " + _groupFile); + } + } + } + + private synchronized void readGroupFile(String groupFile) throws IOException + { + _groupFile = groupFile; + _groupToUserMap.clear(); + _userToGroupMap.clear(); + Properties propertiesFile = new Properties(); + FileInputStream fileInputStream = new FileInputStream(groupFile); + try + { + propertiesFile.load(fileInputStream); + } + finally + { + if(fileInputStream != null) + { + fileInputStream.close(); + } + } + + for (String propertyName : propertiesFile.stringPropertyNames()) + { + validatePropertyNameIsGroupName(propertyName); + + String groupName = propertyName.replaceAll("\\.users$", ""); + String userString = propertiesFile.getProperty(propertyName); + + final Set<String> userSet = buildUserSetFromCommaSeparateValue(userString); + + _groupToUserMap.put(groupName, userSet); + + for (String userName : userSet) + { + Set<String> groupsForThisUser = _userToGroupMap.get(userName); + + if (groupsForThisUser == null) + { + groupsForThisUser = new ConcurrentSkipListSet<String>(); + _userToGroupMap.put(userName, groupsForThisUser); + } + + groupsForThisUser.add(groupName); + } + } + } + + private synchronized void writeGroupFile(String groupFile) throws IOException + { + Properties propertiesFile = new Properties(); + + for (String group : _groupToUserMap.keySet()) + { + Set<String> users = _groupToUserMap.get(group); + String userList = StringUtils.join(users, ","); + + propertiesFile.setProperty(group + ".users", userList); + } + + String comment = "Written " + new Date(); + FileOutputStream fileOutputStream = new FileOutputStream(groupFile); + try + { + propertiesFile.store(fileOutputStream, comment); + } + finally + { + if(fileOutputStream != null) + { + fileOutputStream.close(); + } + } + } + + private void validatePropertyNameIsGroupName(String propertyName) + { + if (!propertyName.endsWith(".users")) + { + throw new IllegalArgumentException( + "Invalid definition with name '" + + propertyName + + "'. Group definitions must end with suffix '.users'"); + } + } + + private ConcurrentSkipListSet<String> buildUserSetFromCommaSeparateValue(String userString) + { + String[] users = userString.split(","); + final ConcurrentSkipListSet<String> userSet = new ConcurrentSkipListSet<String>(); + for (String user : users) + { + final String trimmed = user.trim(); + if (!trimmed.isEmpty()) + { + userSet.add(trimmed); + } + } + return userSet; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java new file mode 100644 index 0000000000..8295f28f9e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManager.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.group; + +import java.io.IOException; +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.security.auth.UsernamePrincipal; + +/** + * Implementation of a group manager whose implementation is backed by a flat group file. + * <p> + * This plugin is configured in the following manner: + * </p> + * <pre> + * <file-group-manager> + * <attributes> + * <attribute> + * <name>groupFile</name> + * <value>${conf}/groups</value> + * </attribute> + * </attributes> + * </file-group-manager> + * </pre> + */ +public class FileGroupManager implements GroupManager +{ + private final FileGroupDatabase _groupDatabase; + + + public FileGroupManager(String groupFile) + { + _groupDatabase = new FileGroupDatabase(); + try + { + _groupDatabase.setGroupFile(groupFile); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Unable to set group file " + groupFile, e); + } + } + + @Override + public Set<Principal> getGroupPrincipalsForUser(String userId) + { + Set<String> groups = _groupDatabase.getGroupsForUser(userId); + if (groups.isEmpty()) + { + return Collections.emptySet(); + } + else + { + Set<Principal> principals = new HashSet<Principal>(); + for (String groupName : groups) + { + principals.add(new GroupPrincipal(groupName)); + } + return principals; + } + } + + @Override + public Set<Principal> getUserPrincipalsForGroup(String group) + { + Set<String> users = _groupDatabase.getUsersInGroup(group); + if (users.isEmpty()) + { + return Collections.emptySet(); + } + else + { + Set<Principal> principals = new HashSet<Principal>(); + for (String user : users) + { + principals.add(new UsernamePrincipal(user)); + } + return principals; + } + } + + @Override + public Set<Principal> getGroupPrincipals() + { + Set<String> groups = _groupDatabase.getAllGroups(); + if (groups.isEmpty()) + { + return Collections.emptySet(); + } + else + { + Set<Principal> principals = new HashSet<Principal>(); + for (String groupName : groups) + { + principals.add(new GroupPrincipal(groupName)); + } + return principals; + } + } + + @Override + public void createGroup(String group) + { + _groupDatabase.createGroup(group); + } + + @Override + public void removeGroup(String group) + { + _groupDatabase.removeGroup(group); + } + + @Override + public void addUserToGroup(String user, String group) + { + _groupDatabase.addUserToGroup(user, group); + } + + @Override + public void removeUserFromGroup(String user, String group) + { + _groupDatabase.removeUserFromGroup(user, group); + + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java new file mode 100644 index 0000000000..5c4730a9c8 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/FileGroupManagerFactory.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.group; + +import static org.apache.qpid.server.util.MapValueConverter.getStringAttribute; + +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.plugin.GroupManagerFactory; + +public class FileGroupManagerFactory implements GroupManagerFactory +{ + static final String FILE_GROUP_MANAGER_TYPE = "file-group-manager"; + static final String FILE = "file"; + + @Override + public GroupManager createInstance(Map<String, Object> attributes) + { + if(!FILE_GROUP_MANAGER_TYPE.equals(getStringAttribute(GroupProvider.TYPE, attributes, null))) + { + return null; + } + + String groupFile = getStringAttribute(FILE, attributes, null); + if (StringUtils.isBlank(groupFile)) + { + throw new IllegalConfigurationException("Path to file containing groups is not specified!"); + } + return new FileGroupManager(groupFile); + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java index 8a9029fbfd..98c12782d8 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/SystemConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupDatabase.java @@ -1,5 +1,4 @@ /* - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -18,25 +17,18 @@ * under the License. * */ +package org.apache.qpid.server.security.group; -package org.apache.qpid.server.configuration; +import java.util.Set; -public interface SystemConfig extends ConfiguredObject<SystemConfigType,SystemConfig> +public interface GroupDatabase { - String getName(); - - String getOperatingSystemName(); - - String getNodeName(); - - - String getOSRelease(); - - String getOSVersion(); - - String getOSArchitecture(); - - void addBroker(BrokerConfig broker); - - void removeBroker(BrokerConfig broker); + Set<String> getAllGroups(); + Set<String> getUsersInGroup(String group); + + void addUserToGroup(String user, String group); + void removeUserFromGroup(String user, String group); + Set<String> getGroupsForUser(String user); + void createGroup(String group); + void removeGroup(String group); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java index 233134abc5..6d2df86919 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/configuration/BindingConfig.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupManager.java @@ -1,5 +1,4 @@ /* - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -18,24 +17,24 @@ * under the License. * */ +package org.apache.qpid.server.security.group; -package org.apache.qpid.server.configuration; - -import java.util.Map; - +import java.security.Principal; +import java.util.Set; -public interface BindingConfig extends ConfiguredObject<BindingConfigType, BindingConfig> +public interface GroupManager { + Set<Principal> getGroupPrincipalsForUser(String user); - ExchangeConfig getExchange(); + Set<Principal> getGroupPrincipals(); - QueueConfig getQueue(); + Set<Principal> getUserPrincipalsForGroup(String group); - String getBindingKey(); + void createGroup(String group); - Map<String, Object> getArguments(); + void removeGroup(String group); - String getOrigin(); + void addUserToGroup(String user, String group); - long getMatches(); -}
\ No newline at end of file + void removeUserFromGroup(String user, String group); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java index 30a503c769..a9590bb964 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipal.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -18,8 +18,9 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.sasl; +package org.apache.qpid.server.security.group; +import java.io.Serializable; import java.security.Principal; import java.security.acl.Group; import java.util.Enumeration; @@ -30,11 +31,11 @@ import java.util.Enumeration; * methods etc throw {@link UnsupportedOperationException}. * */ -public class GroupPrincipal implements Group +public class GroupPrincipal implements Group, Serializable { /** Name of the group */ private final String _groupName; - + public GroupPrincipal(final String groupName) { _groupName = groupName; @@ -83,7 +84,7 @@ public class GroupPrincipal implements Group { return true; } - else + else { if (obj instanceof GroupPrincipal) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java new file mode 100644 index 0000000000..d549b76aab --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/security/group/GroupPrincipalAccessor.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.server.security.group; + +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.qpid.server.model.GroupProvider; +import org.apache.qpid.server.model.adapter.GroupProviderAdapter; + + +public class GroupPrincipalAccessor +{ + private final Collection<GroupProvider> _groupProviders; + + public GroupPrincipalAccessor(Collection<GroupProvider> groupProviders) + { + _groupProviders = groupProviders; + } + + public Set<Principal> getGroupPrincipals(String username) + { + Set<Principal> principals = new HashSet<Principal>(); + for (GroupProvider groupProvider : _groupProviders) + { + Set<Principal> groups = groupProvider.getGroupPrincipalsForUser(username); + if (groups != null) + { + principals.addAll(groups); + } + } + + return Collections.unmodifiableSet(principals); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java b/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java deleted file mode 100644 index bdcfd86f82..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/signal/SignalHandlerTask.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.signal; - -import org.apache.log4j.Logger; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -public abstract class SignalHandlerTask -{ - private static final Logger LOGGER = Logger.getLogger(SignalHandlerTask.class); - - private static final String HANDLE_METHOD = "handle"; - private static final String SUN_MISC_SIGNAL_CLASS = "sun.misc.Signal"; - private static final String SUN_MISC_SIGNAL_HANDLER_CLASS = "sun.misc.SignalHandler"; - - public boolean register(final String signalName) - { - try - { - //try to load the signal handling classes - Class<?> signalClazz = Class.forName(SUN_MISC_SIGNAL_CLASS); - Class<?> handlerClazz = Class.forName(SUN_MISC_SIGNAL_HANDLER_CLASS); - - //create an InvocationHandler that just executes the SignalHandlerTask - InvocationHandler invoker = new InvocationHandler() - { - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable - { - handle(); - - return null; - } - }; - - //create a dynamic proxy implementing SignalHandler - Object handler = Proxy.newProxyInstance(handlerClazz.getClassLoader(), new Class[]{handlerClazz}, invoker); - - //create the Signal to handle - Constructor<?> signalConstructor = signalClazz.getConstructor(String.class); - Object signal = signalConstructor.newInstance(signalName); - - //invoke the Signal.handle(signal, handler) method - Method handleMethod = signalClazz.getMethod(HANDLE_METHOD, signalClazz, handlerClazz); - handleMethod.invoke(null, signal, handler); - } - catch (Exception e) - { - LOGGER.debug("Unable to register handler for Signal " + signalName + " due to exception: " + e, e); - return false; - } - - return true; - } - - public abstract void handle(); - - public static String getPlatformDescription() - { - String name = System.getProperty("os.name"); - String osVer = System.getProperty("os.version"); - String jvmVendor = System.getProperty("java.vm.vendor"); - String jvmName = System.getProperty("java.vm.name"); - String javaRuntimeVer = System.getProperty("java.runtime.version"); - - return "OS: " + name + " " + osVer + ", JVM:" + jvmVendor + " " + jvmName + " " + javaRuntimeVer; - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java index f352bbdd2c..ff41536a23 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java @@ -31,10 +31,10 @@ import org.apache.qpid.framing.MethodDispatcher; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import java.util.concurrent.CopyOnWriteArraySet; @@ -47,32 +47,29 @@ public class AMQStateManager implements AMQMethodListener { private static final Logger _logger = Logger.getLogger(AMQStateManager.class); - private final VirtualHostRegistry _virtualHostRegistry; + private final Broker _broker; private final AMQProtocolSession _protocolSession; /** The current state */ private AMQState _currentState; private CopyOnWriteArraySet<StateListener> _stateListeners = new CopyOnWriteArraySet<StateListener>(); - public AMQStateManager(VirtualHostRegistry virtualHostRegistry, AMQProtocolSession protocolSession) + public AMQStateManager(Broker broker, AMQProtocolSession protocolSession) { - - _virtualHostRegistry = virtualHostRegistry; + _broker = broker; _protocolSession = protocolSession; _currentState = AMQState.CONNECTION_NOT_STARTED; } /** - * Get the ApplicationRegistry associated with this AMQStateManager - * - * returns the application registry associated with the VirtualHostRegistry of the AMQStateManager + * Get the Broker instance * - * @return the ApplicationRegistry + * @return the Broker */ - public IApplicationRegistry getApplicationRegistry() + public Broker getBroker() { - return _virtualHostRegistry.getApplicationRegistry(); + return _broker; } public AMQState getCurrentState() @@ -148,7 +145,7 @@ public class AMQStateManager implements AMQMethodListener public VirtualHostRegistry getVirtualHostRegistry() { - return _virtualHostRegistry; + return _broker.getVirtualHostRegistry(); } public AMQProtocolSession getProtocolSession() @@ -157,13 +154,9 @@ public class AMQStateManager implements AMQMethodListener return _protocolSession; } - /** - * Get the AuthenticationManager associated with the ProtocolSession of the AMQStateManager - * - * @return the AuthenticationManager - */ - public AuthenticationManager getAuthenticationManager() + + public SubjectCreator getSubjectCreator() { - return getApplicationRegistry().getAuthenticationManager(getProtocolSession().getLocalAddress()); + return _broker.getSubjectCreator(getProtocolSession().getLocalAddress()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java index ede01d247e..ab7ef3f55b 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/ConfigurationRecoveryHandler.java @@ -46,19 +46,7 @@ public interface ConfigurationRecoveryHandler public static interface BindingRecoveryHandler { void binding(UUID bindingId, UUID exchangeId, UUID queueId, String bindingName, ByteBuffer buf); - BrokerLinkRecoveryHandler completeBindingRecovery(); - } - - public static interface BrokerLinkRecoveryHandler - { - BridgeRecoveryHandler brokerLink(UUID id, long createTime, Map<String,String> arguments); - void completeBrokerLinkRecovery(); - } - - public static interface BridgeRecoveryHandler - { - void bridge(UUID id, long createTime, Map<String,String> arguments); - void completeBridgeRecoveryForLink(); + void completeBindingRecovery(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java index 655887e5c2..4e7bbf04a6 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java @@ -26,8 +26,6 @@ import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.Bridge; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.queue.AMQQueue; public interface DurableConfigurationStore @@ -122,12 +120,5 @@ public interface DurableConfigurationStore * @throws AMQStoreException If the operation fails for any reason. */ void updateQueue(AMQQueue queue) throws AMQStoreException; - - void createBrokerLink(BrokerLink link) throws AMQStoreException; - - void deleteBrokerLink(BrokerLink link) throws AMQStoreException; - - void createBridge(Bridge bridge) throws AMQStoreException; - - void deleteBridge(Bridge bridge) throws AMQStoreException; + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java index 262d7d0213..3f1d1b9530 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java @@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicLong; /** A simple message store that stores the messages in a thread-safe structure in memory. */ public class MemoryMessageStore extends NullMessageStore { + public static final String TYPE = "Memory"; private final AtomicLong _messageId = new AtomicLong(1); private final AtomicBoolean _closed = new AtomicBoolean(false); @@ -138,6 +139,6 @@ public class MemoryMessageStore extends NullMessageStore @Override public String getStoreType() { - return "Memory"; + return TYPE; } } diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java index 706ab3974a..20b6b7a8a6 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/CompletionCode.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java @@ -18,19 +18,22 @@ * under the License. * */ +package org.apache.qpid.server.store; -package org.apache.qpid.qmf; -public enum CompletionCode +public class MemoryMessageStoreFactory implements MessageStoreFactory { - OK, - UNKNOWN_OBJECT, - UNKNOWN_METHOD, - NOT_IMPLEMENTED, - INVALID_PARAMETER, - FEATURE_NOT_IMPLEMENTED, - FORBIDDEN, - EXCEPTION, - UNKNOWN_PACKAGE, - UNKNOWN_CLASS; + + @Override + public String getType() + { + return MemoryMessageStore.TYPE; + } + + @Override + public MessageStore createMessageStore() + { + return new MemoryMessageStore(); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java new file mode 100644 index 0000000000..0d5a4850f6 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreCreator.java @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.store; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.plugin.QpidServiceLoader; + +public class MessageStoreCreator +{ + private Map<String, MessageStoreFactory> _factories = new HashMap<String, MessageStoreFactory>(); + + public MessageStoreCreator() + { + QpidServiceLoader<MessageStoreFactory> qpidServiceLoader = new QpidServiceLoader<MessageStoreFactory>(); + Iterable<MessageStoreFactory> factories = qpidServiceLoader.atLeastOneInstanceOf(MessageStoreFactory.class); + for (MessageStoreFactory messageStoreFactory : factories) + { + String type = messageStoreFactory.getType(); + MessageStoreFactory factory = _factories.put(type.toLowerCase(), messageStoreFactory); + if (factory != null) + { + throw new IllegalStateException("MessageStoreFactory with type name '" + type + + "' is already registered using class '" + factory.getClass().getName() + "', can not register class '" + + messageStoreFactory.getClass().getName() + "'"); + } + } + } + + public MessageStore createMessageStore(String storeType) + { + MessageStoreFactory factory = _factories.get(storeType.toLowerCase()); + if (factory == null) + { + throw new IllegalConfigurationException("Unknown store type: " + storeType); + } + return factory.createMessageStore(); + } + + public Collection<MessageStoreFactory> getFactories() + { + return Collections.unmodifiableCollection(_factories.values()); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java index 9f9c832732..a1afd02f12 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFEventSeverity.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java @@ -18,16 +18,11 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.store; -public enum QMFEventSeverity +public interface MessageStoreFactory { - EMERGENCY, - ALERT, - CRITICAL, - ERROR, - WARN, - NOTICE, - INFORM, - DEBUG + String getType(); + + MessageStore createMessageStore(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java index be08e309e6..c6bffbc1de 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java @@ -24,8 +24,6 @@ import org.apache.qpid.AMQStoreException; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.Bridge; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.queue.AMQQueue; public abstract class NullMessageStore implements MessageStore @@ -78,26 +76,6 @@ public abstract class NullMessageStore implements MessageStore } @Override - public void createBrokerLink(final BrokerLink link) throws AMQStoreException - { - } - - @Override - public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException - { - } - - @Override - public void createBridge(final Bridge bridge) throws AMQStoreException - { - } - - @Override - public void deleteBridge(final Bridge bridge) throws AMQStoreException - { - } - - @Override public void configureMessageStore(String name, MessageStoreRecoveryHandler recoveryHandler, TransactionLogRecoveryHandler tlogRecoveryHandler, Configuration config) throws Exception diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/State.java b/java/broker/src/main/java/org/apache/qpid/server/store/State.java index 2783637b2a..1d0936cec4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/State.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/State.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.server.store; -import org.apache.qpid.server.configuration.ConfiguredObject; - public enum State { /** The initial state of the store. In practice, the store immediately transitions to the subsequent states. */ @@ -30,7 +28,7 @@ public enum State INITIALISING, /** * The initial set-up of the store has completed. - * If the store is persistent, it has not yet loaded configuration for {@link ConfiguredObject}'s from disk. + * If the store is persistent, it has not yet loaded configuration from disk. * * From the point of view of the user, the store is essentially stopped. */ diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java index 154d7e6535..e9946d1860 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java @@ -23,7 +23,6 @@ package org.apache.qpid.server.store.derby; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; @@ -41,7 +40,6 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -55,12 +53,9 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.Binding; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.Bridge; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.message.EnqueableMessage; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.store.ConfigurationRecoveryHandler; -import org.apache.qpid.server.store.ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler; import org.apache.qpid.server.store.ConfiguredObjectHelper; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.Event; @@ -236,7 +231,7 @@ public class DerbyMessageStore implements MessageStore private static final String DERBY_SINGLE_DB_SHUTDOWN_CODE = "08006"; - private static final String DERBY_STORE_TYPE = "DERBY"; + public static final String TYPE = "DERBY"; private final StateManager _stateManager; @@ -572,8 +567,7 @@ public class DerbyMessageStore implements MessageStore BindingRecoveryHandler brh = qrh.completeQueueRecovery(); _configuredObjectHelper.recoverBindings(brh, configuredObjects); - BrokerLinkRecoveryHandler lrh = brh.completeBindingRecovery(); - recoverBrokerLinks(lrh); + brh.completeBindingRecovery(); } catch (SQLException e) { @@ -581,144 +575,6 @@ public class DerbyMessageStore implements MessageStore } } - private void recoverBrokerLinks(final ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler lrh) - throws SQLException - { - _logger.info("Recovering broker links..."); - - Connection conn = null; - try - { - conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_LINKS); - - try - { - ResultSet rs = stmt.executeQuery(); - - try - { - - while(rs.next()) - { - UUID id = new UUID(rs.getLong(2), rs.getLong(1)); - long createTime = rs.getLong(3); - Blob argumentsAsBlob = rs.getBlob(4); - - byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length()); - - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes)); - int size = dis.readInt(); - - Map<String,String> arguments = new HashMap<String, String>(); - - for(int i = 0; i < size; i++) - { - arguments.put(dis.readUTF(), dis.readUTF()); - } - - ConfigurationRecoveryHandler.BridgeRecoveryHandler brh = lrh.brokerLink(id, createTime, arguments); - - recoverBridges(brh, id); - - } - } - catch (IOException e) - { - throw new SQLException(e.getMessage(), e); - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - - } - finally - { - if(conn != null) - { - conn.close(); - } - } - - } - - private void recoverBridges(final ConfigurationRecoveryHandler.BridgeRecoveryHandler brh, final UUID linkId) - throws SQLException - { - _logger.info("Recovering bridges for link " + linkId + "..."); - - Connection conn = null; - try - { - conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_FROM_BRIDGES); - - try - { - stmt.setLong(1, linkId.getLeastSignificantBits()); - stmt.setLong(2, linkId.getMostSignificantBits()); - - ResultSet rs = stmt.executeQuery(); - - try - { - - while(rs.next()) - { - UUID id = new UUID(rs.getLong(2), rs.getLong(1)); - long createTime = rs.getLong(3); - Blob argumentsAsBlob = rs.getBlob(6); - - byte[] dataAsBytes = argumentsAsBlob.getBytes(1,(int) argumentsAsBlob.length()); - - DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dataAsBytes)); - int size = dis.readInt(); - - Map<String,String> arguments = new HashMap<String, String>(); - - for(int i = 0; i < size; i++) - { - arguments.put(dis.readUTF(), dis.readUTF()); - } - - brh.bridge(id, createTime, arguments); - - } - brh.completeBridgeRecoveryForLink(); - } - catch (IOException e) - { - throw new SQLException(e.getMessage(), e); - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - - } - finally - { - if(conn != null) - { - conn.close(); - } - } - - } - @Override public void close() throws Exception { @@ -975,71 +831,6 @@ public class DerbyMessageStore implements MessageStore } } - @Override - public void createBrokerLink(final BrokerLink link) throws AMQStoreException - { - _logger.debug("public void createBrokerLink(BrokerLink = " + link + "): called"); - - if (_stateManager.isInState(State.ACTIVE)) - { - try - { - Connection conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(FIND_LINK); - try - { - - stmt.setLong(1, link.getQMFId().getLeastSignificantBits()); - stmt.setLong(2, link.getQMFId().getMostSignificantBits()); - ResultSet rs = stmt.executeQuery(); - try - { - - // If we don't have any data in the result set then we can add this queue - if (!rs.next()) - { - PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_LINKS); - - try - { - - insertStmt.setLong(1, link.getQMFId().getLeastSignificantBits()); - insertStmt.setLong(2, link.getQMFId().getMostSignificantBits()); - insertStmt.setLong(3, link.getCreateTime()); - - byte[] argumentBytes = convertStringMapToBytes(link.getArguments()); - ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes); - - insertStmt.setBinaryStream(4,bis,argumentBytes.length); - - insertStmt.execute(); - } - finally - { - insertStmt.close(); - } - } - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - conn.close(); - - } - catch (SQLException e) - { - throw new AMQStoreException("Error writing " + link + " to database: " + e.getMessage(), e); - } - } - } - private byte[] convertStringMapToBytes(final Map<String, String> arguments) throws AMQStoreException { byte[] argumentBytes; @@ -1072,139 +863,7 @@ public class DerbyMessageStore implements MessageStore return argumentBytes; } - @Override - public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException - { - _logger.debug("public void deleteBrokerLink( " + link + "): called"); - Connection conn = null; - PreparedStatement stmt = null; - try - { - conn = newAutoCommitConnection(); - stmt = conn.prepareStatement(DELETE_FROM_LINKS); - stmt.setLong(1, link.getQMFId().getLeastSignificantBits()); - stmt.setLong(2, link.getQMFId().getMostSignificantBits()); - int results = stmt.executeUpdate(); - - if (results == 0) - { - throw new AMQStoreException("Link " + link + " not found"); - } - } - catch (SQLException e) - { - throw new AMQStoreException("Error deleting Link " + link + " from database: " + e.getMessage(), e); - } - finally - { - closePreparedStatement(stmt); - closeConnection(conn); - } - - - } - - @Override - public void createBridge(final Bridge bridge) throws AMQStoreException - { - _logger.debug("public void createBridge(BrokerLink = " + bridge + "): called"); - if (_stateManager.isInState(State.ACTIVE)) - { - try - { - Connection conn = newAutoCommitConnection(); - - PreparedStatement stmt = conn.prepareStatement(FIND_BRIDGE); - try - { - - UUID id = bridge.getQMFId(); - stmt.setLong(1, id.getLeastSignificantBits()); - stmt.setLong(2, id.getMostSignificantBits()); - ResultSet rs = stmt.executeQuery(); - try - { - - // If we don't have any data in the result set then we can add this queue - if (!rs.next()) - { - PreparedStatement insertStmt = conn.prepareStatement(INSERT_INTO_BRIDGES); - - try - { - - insertStmt.setLong(1, id.getLeastSignificantBits()); - insertStmt.setLong(2, id.getMostSignificantBits()); - - insertStmt.setLong(3, bridge.getCreateTime()); - - UUID linkId = bridge.getLink().getQMFId(); - insertStmt.setLong(4, linkId.getLeastSignificantBits()); - insertStmt.setLong(5, linkId.getMostSignificantBits()); - - byte[] argumentBytes = convertStringMapToBytes(bridge.getArguments()); - ByteArrayInputStream bis = new ByteArrayInputStream(argumentBytes); - - insertStmt.setBinaryStream(6,bis,argumentBytes.length); - - insertStmt.execute(); - } - finally - { - insertStmt.close(); - } - } - } - finally - { - rs.close(); - } - } - finally - { - stmt.close(); - } - conn.close(); - - } - catch (SQLException e) - { - throw new AMQStoreException("Error writing " + bridge + " to database: " + e.getMessage(), e); - } - } - } - - @Override - public void deleteBridge(final Bridge bridge) throws AMQStoreException - { - _logger.debug("public void deleteBridge( " + bridge + "): called"); - Connection conn = null; - PreparedStatement stmt = null; - try - { - conn = newAutoCommitConnection(); - stmt = conn.prepareStatement(DELETE_FROM_BRIDGES); - stmt.setLong(1, bridge.getQMFId().getLeastSignificantBits()); - stmt.setLong(2, bridge.getQMFId().getMostSignificantBits()); - int results = stmt.executeUpdate(); - - if (results == 0) - { - throw new AMQStoreException("Bridge " + bridge + " not found"); - } - } - catch (SQLException e) - { - throw new AMQStoreException("Error deleting bridge " + bridge + " from database: " + e.getMessage(), e); - } - finally - { - closePreparedStatement(stmt); - closeConnection(conn); - } - - } @Override public Transaction newTransaction() @@ -2134,8 +1793,9 @@ public class DerbyMessageStore implements MessageStore public ByteBuffer getContent(int offsetInMessage, int size) { ByteBuffer buf = ByteBuffer.allocate(size); - getContent(offsetInMessage, buf); + int length = getContent(offsetInMessage, buf); buf.position(0); + buf.limit(length); return buf; } @@ -2673,7 +2333,7 @@ public class DerbyMessageStore implements MessageStore @Override public String getStoreType() { - return DERBY_STORE_TYPE; + return TYPE; } }
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java index 0e01c27db5..046b503d8a 100644 --- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFType.java +++ b/java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java @@ -18,36 +18,24 @@ * under the License. * */ -package org.apache.qpid.qmf; +package org.apache.qpid.server.store.derby; -public enum QMFType +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.MessageStoreFactory; + +public class DerbyMessageStoreFactory implements MessageStoreFactory { - UINT8, - UINT16, - UINT32, - UINT64, - UNKNOWN, - STR8, - STR16, - ABSTIME, - DELTATIME, - OBJECTREFERENCE, - BOOLEAN, - FLOAT, - DOUBLE, - UUID, - MAP, - INT8, - INT16, - INT32, - INT64, - OBJECT, - LIST, - ARRAY; + @Override + public String getType() + { + return DerbyMessageStore.TYPE; + } - public int codeValue() + @Override + public MessageStore createMessageStore() { - return ordinal()+1; + return new DerbyMessageStore(); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java index c92853e400..6c5cb2e721 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java @@ -27,11 +27,6 @@ import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.AMQChannel; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfigType; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.filter.FilterManagerFactory; import org.apache.qpid.server.flow.FlowCreditManager; @@ -61,8 +56,7 @@ import java.util.concurrent.locks.ReentrantLock; * Encapsulation of a supscription to a queue. <p/> Ties together the protocol session of a subscriber, the consumer tag * that was given out by the broker and the channel id. <p/> */ -public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener, - SubscriptionConfig +public abstract class SubscriptionImpl implements Subscription, FlowCreditManager.FlowCreditManagerListener { private StateListener _stateListener = new StateListener() @@ -91,7 +85,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage private final long _subscriptionID; private LogSubject _logSubject; private LogActor _logActor; - private UUID _qmfId; private final AtomicLong _deliveredCount = new AtomicLong(0); private final AtomicLong _deliveredBytes = new AtomicLong(0); @@ -373,11 +366,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage return _channel; } - public ConfigStore getConfigStore() - { - return getQueue().getConfigStore(); - } - public Long getDelivered() { return _deliveredCount.get(); @@ -391,9 +379,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage } _queue = queue; - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); - _logSubject = new SubscriptionLogSubject(this); _logActor = new SubscriptionActor(CurrentActor.get().getRootMessageLogger(), this); @@ -547,8 +532,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage { _stateChangeLock.unlock(); } - getConfigStore().removeConfiguredObject(this); - //Log Subscription closed CurrentActor.get().message(_logSubject, SubscriptionMessages.CLOSE()); } @@ -752,11 +735,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage return "WINDOW"; } - public SessionConfig getSessionConfig() - { - return getChannel(); - } - public boolean isBrowsing() { return isBrowser(); @@ -767,32 +745,16 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage return true; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - public boolean isDurable() { return false; } - public SubscriptionConfigType getConfigType() - { - return SubscriptionConfigType.getInstance(); - } - public boolean isExclusive() { return getQueue().hasExclusiveSubscriber(); } - public ConfiguredObject getParent() - { - return getSessionConfig(); - } - public String getName() { return String.valueOf(_consumerTag); diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java index dfd9315226..b9bba49fab 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java +++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java @@ -24,11 +24,6 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicContentHeaderProperties; import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfig; -import org.apache.qpid.server.configuration.SubscriptionConfigType; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.flow.CreditCreditManager; @@ -86,7 +81,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, SubscriptionConfig, LogSubject +public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCreditManagerListener, LogSubject { private final long _subscriptionID; @@ -125,7 +120,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr private LogActor _logActor; private final Map<String, Object> _properties = new ConcurrentHashMap<String, Object>(); - private UUID _qmfId; private String _traceExclude; private String _trace; private final long _createTime = System.currentTimeMillis(); @@ -192,8 +186,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr Map<String, Object> arguments = queue.getArguments(); _traceExclude = (String) arguments.get("qpid.trace.exclude"); _trace = (String) arguments.get("qpid.trace.id"); - _qmfId = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); String filterLogString = null; _logActor = GenericActor.getInstance(this); @@ -283,7 +275,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr } } _creditManager.removeListener(this); - getConfigStore().removeConfiguredObject(this); CurrentActor.get().message(getLogSubject(), SubscriptionMessages.CLOSE()); } finally @@ -295,11 +286,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr } - public ConfigStore getConfigStore() - { - return getQueue().getConfigStore(); - } - public Long getDelivered() { return _deliveredCount.get(); @@ -970,12 +956,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return _session; } - - public SessionConfig getSessionConfig() - { - return getSessionModel(); - } - public boolean isBrowsing() { return _acquireMode == MessageAcquireMode.NOT_ACQUIRED; @@ -986,20 +966,11 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return getQueue().hasExclusiveSubscriber(); } - public ConfiguredObject getParent() - { - return getSessionConfig(); - } - public boolean isDurable() { return false; } - public SubscriptionConfigType getConfigType() - { - return SubscriptionConfigType.getInstance(); - } public boolean isExplicitAcknowledge() { @@ -1011,12 +982,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return _flowMode.toString(); } - @Override - public UUID getQMFId() - { - return _qmfId; - } - public String getName() { return _destination; diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java deleted file mode 100644 index 7c4188bfcd..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.transport; - -import org.apache.qpid.server.protocol.AmqpProtocolVersion; -import org.apache.qpid.transport.network.NetworkTransport; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -public class QpidAcceptor -{ - public enum Transport - { - TCP("TCP"), - SSL("TCP/SSL"); - - private final String _asString; - - Transport(String asString) - { - _asString = asString; - } - - public String toString() - { - return _asString; - } - } - - private NetworkTransport _networkTransport; - private Transport _transport; - private Set<AmqpProtocolVersion> _supported; - - - public QpidAcceptor(NetworkTransport transport, Transport protocol, Set<AmqpProtocolVersion> supported) - { - _networkTransport = transport; - _transport = protocol; - _supported = Collections.unmodifiableSet(new HashSet<AmqpProtocolVersion>(supported)); - } - - public NetworkTransport getNetworkTransport() - { - return _networkTransport; - } - - public Transport getTransport() - { - return _transport; - } - - public Set<AmqpProtocolVersion> getSupported() - { - return _supported; - } - - public String toString() - { - return _transport.toString(); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java index f21026794f..58de6a0cdf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java @@ -20,17 +20,16 @@ */ package org.apache.qpid.server.transport; +import java.net.SocketAddress; import java.security.Principal; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; -import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import javax.security.auth.Subject; import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.configuration.ConnectionConfig; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; @@ -39,6 +38,7 @@ import org.apache.qpid.server.logging.messages.ConnectionMessages; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.security.AuthorizationHolder; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Connection; @@ -48,6 +48,7 @@ import org.apache.qpid.transport.ExecutionException; import org.apache.qpid.transport.Method; import org.apache.qpid.transport.ProtocolEvent; import org.apache.qpid.transport.Session; +import org.apache.qpid.transport.network.NetworkConnection; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CONNECTION_FORMAT; import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.SOCKET_FORMAT; @@ -55,7 +56,6 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.USER_FORM public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder { - private ConnectionConfig _config; private Runnable _onOpenTask; private AtomicBoolean _logClosed = new AtomicBoolean(false); private LogActor _actor = GenericActor.getInstance(this); @@ -69,6 +69,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, private AtomicLong _lastIoTime = new AtomicLong(); private boolean _blocking; private Principal _peerPrincipal; + private NetworkConnection _networkConnection; public ServerConnection(final long connectionId) { @@ -147,16 +148,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel, initialiseStatistics(); } - public void setConnectionConfig(final ConnectionConfig config) - { - _config = config; - } - - public ConnectionConfig getConfig() - { - return _config; - } - public void onOpen(final Runnable task) { _onOpenTask = task; @@ -228,7 +219,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, MessageFormat.format(CONNECTION_FORMAT, getConnectionId(), getClientId(), - getConfig().getAddress(), + getRemoteAddressString(), getVirtualHost().getName()) + "] "; } @@ -238,7 +229,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, MessageFormat.format(USER_FORMAT, getConnectionId(), getClientId(), - getConfig().getAddress()) + getRemoteAddressString()) + "] "; } @@ -247,7 +238,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, return "[" + MessageFormat.format(SOCKET_FORMAT, getConnectionId(), - getConfig().getAddress()) + getRemoteAddressString()) + "] "; } } @@ -396,7 +387,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, else { _authorizedSubject = authorizedSubject; - _authorizedPrincipal = authorizedSubject.getPrincipals().iterator().next(); + _authorizedPrincipal = AuthenticatedPrincipal.getAuthenticatedPrincipalFromSubject(authorizedSubject); } } @@ -417,7 +408,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel, public String getRemoteAddressString() { - return getConfig().getAddress(); + return String.valueOf(getRemoteAddress()); } public String getUserName() @@ -489,4 +480,32 @@ public class ServerConnection extends Connection implements AMQConnectionModel, { _peerPrincipal = peerPrincipal; } + + @Override + public void setRemoteAddress(SocketAddress remoteAddress) + { + super.setRemoteAddress(remoteAddress); + } + + @Override + public void setLocalAddress(SocketAddress localAddress) + { + super.setLocalAddress(localAddress); + } + + public void setNetworkConnection(NetworkConnection network) + { + _networkConnection = network; + } + + public NetworkConnection getNetworkConnection() + { + return _networkConnection; + } + + public void doHeartbeat() + { + super.doHeartBeat(); + + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java index c13f63b44d..f3153fde62 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java @@ -32,18 +32,19 @@ import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.qpid.common.ServerPropertyNames; import org.apache.qpid.properties.ConnectionStartProperties; -import org.apache.qpid.protocol.ProtocolEngine; -import org.apache.qpid.server.configuration.BrokerConfig; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.protocol.AMQConnectionModel; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.subscription.Subscription_0_10; import org.apache.qpid.server.virtualhost.State; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.*; +import org.apache.qpid.transport.network.NetworkConnection; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,36 +54,49 @@ public class ServerConnectionDelegate extends ServerDelegate { private static final Logger LOGGER = LoggerFactory.getLogger(ServerConnectionDelegate.class); + private final Broker _broker; private final String _localFQDN; - private final IApplicationRegistry _appRegistry; private int _maxNoOfChannels; private Map<String,Object> _clientProperties; - private final AuthenticationManager _authManager; + private final SubjectCreator _subjectCreator; - public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN, AuthenticationManager authManager) + public ServerConnectionDelegate(Broker broker, String localFQDN, SubjectCreator subjectCreator) { - this(createConnectionProperties(appRegistry.getBrokerConfig()), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN, authManager); + this(createConnectionProperties(broker), Collections.singletonList((Object)"en_US"), broker, localFQDN, subjectCreator); } private ServerConnectionDelegate(Map<String, Object> properties, List<Object> locales, - IApplicationRegistry appRegistry, + Broker broker, String localFQDN, - AuthenticationManager authManager) + SubjectCreator subjectCreator) { - super(properties, parseToList(authManager.getMechanisms()), locales); + super(properties, parseToList(subjectCreator.getMechanisms()), locales); - _appRegistry = appRegistry; + _broker = broker; _localFQDN = localFQDN; - _maxNoOfChannels = appRegistry.getConfiguration().getMaxChannelCount(); - _authManager = authManager; + _maxNoOfChannels = (Integer)broker.getAttribute(Broker.SESSION_COUNT_LIMIT); + _subjectCreator = subjectCreator; + } + + private static List<String> getFeatures(Broker broker) + { + String brokerDisabledFeatures = System.getProperty(BrokerProperties.PROPERTY_DISABLED_FEATURES); + final List<String> features = new ArrayList<String>(); + if (brokerDisabledFeatures == null || !brokerDisabledFeatures.contains(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR)) + { + features.add(ServerPropertyNames.FEATURE_QPID_JMS_SELECTOR); + } + + return Collections.unmodifiableList(features); } - private static Map<String, Object> createConnectionProperties(final BrokerConfig brokerConfig) + private static Map<String, Object> createConnectionProperties(final Broker broker) { final Map<String,Object> map = new HashMap<String,Object>(2); - map.put(ServerPropertyNames.FEDERATION_TAG, brokerConfig.getFederationTag()); - final List<String> features = brokerConfig.getFeatures(); + // Federation tag is used by the client to identify the broker instance + map.put(ServerPropertyNames.FEDERATION_TAG, broker.getId().toString()); + final List<String> features = getFeatures(broker); if (features != null && features.size() > 0) { map.put(ServerPropertyNames.QPID_FEATURES, features); @@ -112,14 +126,14 @@ public class ServerConnectionDelegate extends ServerDelegate protected SaslServer createSaslServer(Connection conn, String mechanism) throws SaslException { - return _authManager.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal()); + return _subjectCreator.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal()); } protected void secure(final SaslServer ss, final Connection conn, final byte[] response) { final ServerConnection sconn = (ServerConnection) conn; - final AuthenticationResult authResult = _authManager.authenticate(ss, response); + final SubjectAuthenticationResult authResult = _subjectCreator.authenticate(ss, response); if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus())) { @@ -166,7 +180,7 @@ public class ServerConnectionDelegate extends ServerDelegate { vhostName = ""; } - vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName); + vhost = _broker.getVirtualHostRegistry().getVirtualHost(vhostName); SecurityManager.setThreadSubject(sconn.getAuthorizedSubject()); @@ -174,7 +188,7 @@ public class ServerConnectionDelegate extends ServerDelegate { sconn.setVirtualHost(vhost); - if (!vhost.getSecurityManager().accessVirtualhost(vhostName, ((ProtocolEngine) sconn.getConfig()).getRemoteAddress())) + if (!vhost.getSecurityManager().accessVirtualhost(vhostName, sconn.getRemoteAddress())) { sconn.setState(Connection.State.CLOSING); sconn.invoke(new ConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, "Permission denied '"+vhostName+"'")); @@ -215,14 +229,18 @@ public class ServerConnectionDelegate extends ServerDelegate return; } - setConnectionTuneOkChannelMax(sconn, okChannelMax); - } + if(ok.hasHeartbeat()) + { + final int heartbeat = ok.getHeartbeat(); + if(heartbeat > 0) + { + final NetworkConnection networkConnection = sconn.getNetworkConnection(); + networkConnection.setMaxReadIdle(2 * heartbeat); + networkConnection.setMaxWriteIdle(heartbeat); + } + } - @Override - protected int getHeartbeatMax() - { - //TODO: implement broker support for actually sending heartbeats - return 0; + setConnectionTuneOkChannelMax(sconn, okChannelMax); } @Override diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java index f82b25b3d6..6152ddd228 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java @@ -42,13 +42,8 @@ import javax.security.auth.Subject; import org.apache.qpid.AMQException; import org.apache.qpid.AMQStoreException; import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.ProtocolEngine; import org.apache.qpid.server.TransactionTimeoutHelper; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; -import org.apache.qpid.server.configuration.ConnectionConfig; -import org.apache.qpid.server.configuration.SessionConfig; -import org.apache.qpid.server.configuration.SessionConfigType; +import org.apache.qpid.server.TransactionTimeoutHelper.CloseAction; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.LogSubject; import org.apache.qpid.server.logging.actors.CurrentActor; @@ -91,7 +86,7 @@ import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_F import static org.apache.qpid.util.Serial.gt; public class ServerSession extends Session - implements AuthorizationHolder, SessionConfig, + implements AuthorizationHolder, AMQSessionModel, LogSubject, AsyncAutoCommitTransaction.FutureRecorder { private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class); @@ -100,8 +95,7 @@ public class ServerSession extends Session private static final int PRODUCER_CREDIT_TOPUP_THRESHOLD = 1 << 30; private static final int UNFINISHED_COMMAND_QUEUE_THRESHOLD = 500; - private final UUID _id; - private ConnectionConfig _connectionConfig; + private final UUID _id = UUID.randomUUID(); private long _createTime = System.currentTimeMillis(); private LogActor _actor = GenericActor.getInstance(this); @@ -139,7 +133,6 @@ public class ServerSession extends Session private final AtomicLong _txnCommits = new AtomicLong(0); private final AtomicLong _txnRejects = new AtomicLong(0); private final AtomicLong _txnCount = new AtomicLong(0); - private final AtomicLong _txnUpdateTime = new AtomicLong(0); private Map<String, Subscription_0_10> _subscriptions = new ConcurrentHashMap<String, Subscription_0_10>(); @@ -147,21 +140,21 @@ public class ServerSession extends Session private final TransactionTimeoutHelper _transactionTimeoutHelper; - ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry) - { - this(connection, delegate, name, expiry, ((ServerConnection)connection).getConfig()); - } - public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry, ConnectionConfig connConfig) + public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry) { super(connection, delegate, name, expiry); - _connectionConfig = connConfig; _transaction = new AsyncAutoCommitTransaction(this.getMessageStore(),this); _logSubject = new ChannelLogSubject(this); - _id = getConfigStore().createId(); - getConfigStore().addConfiguredObject(this); - _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject); + _transactionTimeoutHelper = new TransactionTimeoutHelper(_logSubject, new CloseAction() + { + @Override + public void doTimeoutAction(String reason) throws AMQException + { + getConnectionModel().closeSession(ServerSession.this, AMQConstant.RESOURCE_ERROR, reason); + } + }); } protected void setState(State state) @@ -184,12 +177,6 @@ public class ServerSession extends Session invoke(new MessageStop("")); } - private ConfigStore getConfigStore() - { - return getConnectionConfig().getConfigStore(); - } - - @Override protected boolean isFull(int id) { @@ -206,9 +193,8 @@ public class ServerSession extends Session } getConnectionModel().registerMessageReceived(message.getSize(), message.getArrivalTime()); PostEnqueueAction postTransactionAction = new PostEnqueueAction(queues, message, isTransactional()) ; - _transaction.enqueue(queues,message, postTransactionAction, 0L); + _transaction.enqueue(queues,message, postTransactionAction); incrementOutstandingTxnsIfNecessary(); - updateTransactionalActivity(); } @@ -389,8 +375,6 @@ public class ServerSession extends Session } _messageDispositionListenerMap.clear(); - getConfigStore().removeConfiguredObject(this); - for (Task task : _taskList) { task.doTask(this); @@ -424,7 +408,6 @@ public class ServerSession extends Session entry.release(); } }); - updateTransactionalActivity(); } public Collection<Subscription_0_10> getSubscriptions() @@ -470,11 +453,6 @@ public class ServerSession extends Session return _transaction.isTransactional(); } - public boolean inTransaction() - { - return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0; - } - public void selectTx() { _transaction = new LocalTransaction(this.getMessageStore()); @@ -609,22 +587,6 @@ public class ServerSession extends Session } } - /** - * Update last transaction activity timestamp - */ - public void updateTransactionalActivity() - { - if (isTransactional()) - { - _txnUpdateTime.set(System.currentTimeMillis()); - } - } - - public Long getTxnStarts() - { - return _txnStarts.get(); - } - public Long getTxnCommits() { return _txnCommits.get(); @@ -682,23 +644,7 @@ public class ServerSession extends Session public VirtualHost getVirtualHost() { - return (VirtualHost) _connectionConfig.getVirtualHost(); - } - - @Override - public UUID getQMFId() - { - return _id; - } - - public SessionConfigType getConfigType() - { - return SessionConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getVirtualHost(); + return getConnection().getVirtualHost(); } public boolean isDurable() @@ -706,44 +652,16 @@ public class ServerSession extends Session return false; } - public boolean isAttached() - { - return true; - } - - public long getDetachedLifespan() - { - return 0; - } - - public Long getExpiryTime() - { - return null; - } - - public Long getMaxClientRate() - { - return null; - } - - public ConnectionConfig getConnectionConfig() - { - return _connectionConfig; - } - - public String getSessionName() - { - return getName().toString(); - } public long getCreateTime() { return _createTime; } - public void mgmtClose() + @Override + public UUID getId() { - close(); + return _id; } public AMQConnectionModel getConnectionModel() @@ -774,28 +692,7 @@ public class ServerSession extends Session public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException { - if (inTransaction()) - { - long currentTime = System.currentTimeMillis(); - long openTime = currentTime - _transaction.getTransactionStartTime(); - long idleTime = currentTime - _txnUpdateTime.get(); - - _transactionTimeoutHelper.logIfNecessary(idleTime, idleWarn, ChannelMessages.IDLE_TXN(idleTime), - TransactionTimeoutHelper.IDLE_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(idleTime, idleClose)) - { - getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out"); - return; - } - - _transactionTimeoutHelper.logIfNecessary(openTime, openWarn, ChannelMessages.OPEN_TXN(openTime), - TransactionTimeoutHelper.OPEN_TRANSACTION_ALERT); - if (_transactionTimeoutHelper.isTimedOut(openTime, openClose)) - { - getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out"); - return; - } - } + _transactionTimeoutHelper.checkIdleOrOpenTimes(_transaction, openWarn, openClose, idleWarn, idleClose); } public void block(AMQQueue queue) @@ -878,9 +775,7 @@ public class ServerSession extends Session ? getConnection().getConnectionId() : -1; - String remoteAddress = _connectionConfig instanceof ProtocolEngine - ? ((ProtocolEngine) _connectionConfig).getRemoteAddress().toString() - : ""; + String remoteAddress = String.valueOf(getConnection().getRemoteAddress()); return "[" + MessageFormat.format(CHANNEL_FORMAT, connectionId, @@ -1065,14 +960,16 @@ public class ServerSession extends Session super.setClose(close); } - public int compareTo(AMQSessionModel session) + @Override + public int getConsumerCount() { - return getQMFId().compareTo(session.getQMFId()); + return _subscriptions.values().size(); } @Override - public int getConsumerCount() + public int compareTo(AMQSessionModel o) { - return _subscriptions.values().size(); + return getId().compareTo(o.getId()); } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java index 05963ee874..d83bd1c4dc 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java +++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java @@ -31,7 +31,6 @@ import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeInUseException; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.exchange.ExchangeType; import org.apache.qpid.server.exchange.HeadersExchange; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.filter.FilterManagerFactory; @@ -41,11 +40,11 @@ import org.apache.qpid.server.logging.messages.ExchangeMessages; import org.apache.qpid.server.message.MessageMetaData_0_10; import org.apache.qpid.server.message.MessageTransferMessage; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; @@ -1266,18 +1265,12 @@ public class ServerSessionDelegate extends SessionDelegate } } queueRegistry.registerQueue(queue); - boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister(); - if (autoRegister) - { - - ExchangeRegistry exchangeRegistry = getExchangeRegistry(session); + ExchangeRegistry exchangeRegistry = getExchangeRegistry(session); - Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); + Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); - virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null); - - } + virtualHost.getBindingFactory().addBinding(queueName, queue, defaultExchange, null); if (method.hasAutoDelete() && method.getAutoDelete() diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java index efd7850a49..43e60c8e13 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AsyncAutoCommitTransaction.java @@ -66,11 +66,18 @@ public class AsyncAutoCommitTransaction implements ServerTransaction _futureRecorder = recorder; } + @Override public long getTransactionStartTime() { return 0L; } + @Override + public long getTransactionUpdateTime() + { + return 0L; + } + /** * Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered * by the caller are executed immediately. @@ -241,7 +248,7 @@ public class AsyncAutoCommitTransaction implements ServerTransaction } - public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime) + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction) { Transaction txn = null; try diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java index e5a7df6880..8a9479a2d4 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java @@ -52,11 +52,18 @@ public class AutoCommitTransaction implements ServerTransaction _messageStore = transactionLog; } + @Override public long getTransactionStartTime() { return 0L; } + @Override + public long getTransactionUpdateTime() + { + return 0L; + } + /** * Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered * by the caller are executed immediately. @@ -178,7 +185,7 @@ public class AutoCommitTransaction implements ServerTransaction } - public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime) + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction) { Transaction txn = null; try @@ -270,4 +277,6 @@ public class AutoCommitTransaction implements ServerTransaction } } + + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java index 05d0110e9b..ab987f0fb9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java @@ -26,7 +26,6 @@ import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueEntry; import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.Transaction; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.Xid; @@ -39,10 +38,6 @@ public class DistributedTransaction implements ServerTransaction private final AutoCommitTransaction _autoCommitTransaction; - private volatile Transaction _transaction; - - private long _txnStartTime = 0L; - private DtxBranch _branch; private AMQSessionModel _session; private VirtualHost _vhost; @@ -55,9 +50,16 @@ public class DistributedTransaction implements ServerTransaction _autoCommitTransaction = new AutoCommitTransaction(vhost.getMessageStore()); } + @Override public long getTransactionStartTime() { - return _txnStartTime; + return 0; + } + + @Override + public long getTransactionUpdateTime() + { + return 0; } public void addPostTransactionAction(Action postTransactionAction) @@ -107,7 +109,7 @@ public class DistributedTransaction implements ServerTransaction { _branch.enqueue(queue, message); _branch.addPostTransactionAcion(postTransactionAction); - enqueue(Collections.singletonList(queue), message, postTransactionAction, System.currentTimeMillis()); + enqueue(Collections.singletonList(queue), message, postTransactionAction); } else { @@ -116,7 +118,7 @@ public class DistributedTransaction implements ServerTransaction } public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, - Action postTransactionAction, long currentTime) + Action postTransactionAction) { if(_branch != null) { @@ -128,7 +130,7 @@ public class DistributedTransaction implements ServerTransaction } else { - _autoCommitTransaction.enqueue(queues, message, postTransactionAction, currentTime); + _autoCommitTransaction.enqueue(queues, message, postTransactionAction); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java index 3fbcff7e2c..afa7cb0fb4 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java @@ -49,25 +49,42 @@ public class LocalTransaction implements ServerTransaction private final List<Action> _postTransactionActions = new ArrayList<Action>(); private volatile Transaction _transaction; - private MessageStore _transactionLog; - private long _txnStartTime = 0L; + private final ActivityTimeAccessor _activityTime; + private final MessageStore _transactionLog; + private volatile long _txnStartTime = 0L; + private volatile long _txnUpdateTime = 0l; private StoreFuture _asyncTran; public LocalTransaction(MessageStore transactionLog) { - _transactionLog = transactionLog; + this(transactionLog, new ActivityTimeAccessor() + { + @Override + public long getActivityTime() + { + return System.currentTimeMillis(); + } + }); } - - public boolean inTransaction() + + public LocalTransaction(MessageStore transactionLog, ActivityTimeAccessor activityTime) { - return _transaction != null; + _transactionLog = transactionLog; + _activityTime = activityTime; } + @Override public long getTransactionStartTime() { return _txnStartTime; } + @Override + public long getTransactionUpdateTime() + { + return _txnUpdateTime; + } + public void addPostTransactionAction(Action postTransactionAction) { sync(); @@ -78,6 +95,7 @@ public class LocalTransaction implements ServerTransaction { sync(); _postTransactionActions.add(postTransactionAction); + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); if(message.isPersistent() && queue.isDurable()) { @@ -104,6 +122,7 @@ public class LocalTransaction implements ServerTransaction { sync(); _postTransactionActions.add(postTransactionAction); + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); try { @@ -180,6 +199,7 @@ public class LocalTransaction implements ServerTransaction { sync(); _postTransactionActions.add(postTransactionAction); + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); if(message.isPersistent() && queue.isDurable()) { @@ -189,7 +209,7 @@ public class LocalTransaction implements ServerTransaction { _logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString()); } - + beginTranIfNecessary(); _transaction.enqueueMessage(queue, message); } @@ -202,15 +222,11 @@ public class LocalTransaction implements ServerTransaction } } - public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime) + public void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction) { sync(); _postTransactionActions.add(postTransactionAction); - - if (_txnStartTime == 0L) - { - _txnStartTime = currentTime == 0L ? System.currentTimeMillis() : currentTime; - } + initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime(); if(message.isPersistent()) { @@ -224,8 +240,7 @@ public class LocalTransaction implements ServerTransaction { _logger.debug("Enqueue of message number " + message.getMessageNumber() + " to transaction log. Queue : " + queue.getNameShortString() ); } - - + beginTranIfNecessary(); _transaction.enqueueMessage(queue, message); } @@ -378,16 +393,24 @@ public class LocalTransaction implements ServerTransaction } throw new RuntimeException("Failed to commit transaction", e); } - - } private void doPostTransactionActions() { + if(_logger.isDebugEnabled()) + { + _logger.debug("Beginning " + _postTransactionActions.size() + " post transaction actions"); + } + for(int i = 0; i < _postTransactionActions.size(); i++) { _postTransactionActions.get(i).postCommit(); } + + if(_logger.isDebugEnabled()) + { + _logger.debug("Completed post transaction actions"); + } } public void rollback() @@ -427,16 +450,34 @@ public class LocalTransaction implements ServerTransaction } } + private void initTransactionStartTimeIfNecessaryAndAdvanceUpdateTime() + { + long currentTime = _activityTime.getActivityTime(); + + if (_txnStartTime == 0) + { + _txnStartTime = currentTime; + } + _txnUpdateTime = currentTime; + } + private void resetDetails() { _asyncTran = null; _transaction = null; - _postTransactionActions.clear(); + _postTransactionActions.clear(); _txnStartTime = 0L; + _txnUpdateTime = 0; } public boolean isTransactional() { return true; } + + public interface ActivityTimeAccessor + { + long getActivityTime(); + } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java index c568ae67aa..8acac00479 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java +++ b/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java @@ -55,11 +55,18 @@ public interface ServerTransaction /** * Return the time the current transaction started. - * + * * @return the time this transaction started or 0 if not in a transaction */ long getTransactionStartTime(); + /** + * Return the time of the last activity on the current transaction. + * + * @return the time of the last activity or 0 if not in a transaction + */ + long getTransactionUpdateTime(); + /** * Register an Action for execution after transaction commit or rollback. Actions * will be executed in the order in which they are registered. @@ -92,7 +99,7 @@ public interface ServerTransaction * * Store operations will result only for a persistent messages on durable queues. */ - void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction, long currentTime); + void enqueue(List<? extends BaseQueue> queues, EnqueableMessage message, Action postTransactionAction); /** * Commit the transaction represented by this object. diff --git a/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java b/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java new file mode 100644 index 0000000000..aa7b4afcae --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java @@ -0,0 +1,361 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.util; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class MapValueConverter +{ + + public static String getStringAttribute(String name, Map<String,Object> attributes, String defaultVal) + { + final Object value = attributes.get(name); + return toString(value, defaultVal); + } + + public static String toString(final Object value) + { + return toString(value, null); + } + + public static String toString(final Object value, String defaultVal) + { + if (value == null) + { + return defaultVal; + } + else if (value instanceof String) + { + return (String)value; + } + return String.valueOf(value); + } + + public static String getStringAttribute(String name, Map<String, Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getStringAttribute(name, attributes, null); + } + + private static void assertMandatoryAttribute(String name, Map<String, Object> attributes) + { + if (!attributes.containsKey(name)) + { + throw new IllegalArgumentException("Value for attribute " + name + " is not found"); + } + } + + public static Map<String,Object> getMapAttribute(String name, Map<String,Object> attributes, Map<String,Object> defaultVal) + { + final Object value = attributes.get(name); + if(value == null) + { + return defaultVal; + } + else if(value instanceof Map) + { + @SuppressWarnings("unchecked") + Map<String,Object> retVal = (Map<String,Object>) value; + return retVal; + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Map"); + } + } + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static <E extends Enum> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes, E defaultVal) + { + Object obj = attributes.get(name); + if(obj == null) + { + return defaultVal; + } + else if(clazz.isInstance(obj)) + { + return (E) obj; + } + else if(obj instanceof String) + { + return (E) Enum.valueOf(clazz, (String)obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + clazz.getSimpleName()); + } + } + + public static <E extends Enum<?>> E getEnumAttribute(Class<E> clazz, String name, Map<String,Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getEnumAttribute(clazz, name, attributes, null); + } + + @SuppressWarnings({ "unchecked" }) + public static <T extends Enum<T>> T toEnum(String name, Object rawValue, Class<T> enumType) + { + if (enumType.isInstance(rawValue)) + { + return (T) rawValue; + } + else if (rawValue instanceof String) + { + return (T) Enum.valueOf(enumType, (String) rawValue); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type " + + enumType.getSimpleName()); + } + } + + public static Boolean getBooleanAttribute(String name, Map<String,Object> attributes, Boolean defaultValue) + { + Object obj = attributes.get(name); + return toBoolean(name, obj, defaultValue); + } + + public static Boolean toBoolean(String name, Object obj) + { + return toBoolean(name, obj, null); + } + + public static Boolean toBoolean(String name, Object obj, Boolean defaultValue) + { + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Boolean) + { + return (Boolean) obj; + } + else if(obj instanceof String) + { + return Boolean.parseBoolean((String) obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Boolean"); + } + } + + + public static boolean getBooleanAttribute(String name, Map<String, Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getBooleanAttribute(name, attributes, null); + } + + public static Integer getIntegerAttribute(String name, Map<String,Object> attributes, Integer defaultValue) + { + Object obj = attributes.get(name); + return toInteger(name, obj, defaultValue); + } + + public static Integer toInteger(String name, Object obj) + { + return toInteger(name, obj, null); + } + + public static Integer toInteger(String name, Object obj, Integer defaultValue) + { + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Number) + { + return ((Number) obj).intValue(); + } + else if(obj instanceof String) + { + return Integer.valueOf((String) obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Integer"); + } + } + + public static Integer getIntegerAttribute(String name, Map<String,Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getIntegerAttribute(name, attributes, null); + } + + public static Long getLongAttribute(String name, Map<String,Object> attributes, Long defaultValue) + { + Object obj = attributes.get(name); + return toLong(name, obj, defaultValue); + } + + public static Long toLong(String name, Object obj) + { + return toLong(name, obj, null); + } + + public static Long toLong(String name, Object obj, Long defaultValue) + { + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Number) + { + return ((Number) obj).longValue(); + } + else if(obj instanceof String) + { + return Long.valueOf((String) obj); + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Long"); + } + } + + public static <T> Set<T> getSetAttribute(String name, Map<String,Object> attributes) + { + assertMandatoryAttribute(name, attributes); + return getSetAttribute(name, attributes, Collections.<T>emptySet()); + } + + @SuppressWarnings("unchecked") + public static <T> Set<T> getSetAttribute(String name, Map<String,Object> attributes, Set<T> defaultValue) + { + Object obj = attributes.get(name); + if(obj == null) + { + return defaultValue; + } + else if(obj instanceof Set) + { + return (Set<T>) obj; + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + " is not of required type Set"); + } + } + + @SuppressWarnings("unchecked") + public static <T extends Enum<T>> Set<T> getEnumSetAttribute(String name, Map<String, Object> attributes, Class<T> clazz) + { + Object obj = attributes.get(name); + Object[] items = null; + if (obj == null) + { + return null; + } + else if (obj instanceof Collection) + { + Collection<?> data = (Collection<?>) obj; + items = data.toArray(new Object[data.size()]); + } + else if (obj instanceof String[]) + { + items = (String[]) obj; + } + else if (obj instanceof Object[]) + { + items = (Object[]) obj; + } + else + { + throw new IllegalArgumentException("Value for attribute " + name + "[" + obj + + "] cannot be converted into set of enum of " + clazz); + } + Set<T> set = new HashSet<T>(); + for (int i = 0; i < items.length; i++) + { + T item = null; + Object value = items[i]; + if (value instanceof String) + { + item = (T) Enum.valueOf(clazz, (String) value); + } + else if (clazz.isInstance(value)) + { + item = (T) value; + } + else + { + throw new IllegalArgumentException("Cannot convert " + value + " from [" + obj + "] into enum of " + clazz + + " for attribute " + name); + } + set.add(item); + } + return set; + } + + @SuppressWarnings("unchecked") + public static Map<String, Object> convert(Map<String, Object> configurationAttributes, Map<String, Class<?>> attributeTypes) + { + Map<String, Object> attributes = new HashMap<String, Object>(); + for (Map.Entry<String, Class<?>> attributeEntry : attributeTypes.entrySet()) + { + String attributeName = attributeEntry.getKey(); + if (configurationAttributes.containsKey(attributeName)) + { + Class<?> classObject = attributeEntry.getValue(); + Object rawValue = configurationAttributes.get(attributeName); + Object value = null; + if (classObject == Long.class || classObject == long.class) + { + value = toLong(attributeName, rawValue); + } + else if (classObject == Integer.class || classObject == int.class) + { + value = toInteger(attributeName, rawValue); + } + else if (classObject == Boolean.class || classObject == boolean.class) + { + value = toBoolean(attributeName, rawValue); + } + else if (classObject == String.class) + { + value = toString(rawValue); + } + else if (Enum.class.isAssignableFrom(classObject)) + { + @SuppressWarnings("rawtypes") + Class<Enum> enumType = (Class<Enum>)classObject; + value = toEnum(attributeName, rawValue, enumType); + } + else + { + throw new IllegalArgumentException("Cannot convert '" + rawValue + "' into " + classObject); + } + attributes.put(attributeName, value); + } + } + return attributes; + } + +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index f810360662..d24f79c56c 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -25,13 +25,10 @@ import java.util.UUID; import java.util.concurrent.ScheduledFuture; import org.apache.qpid.common.Closeable; import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.VirtualHostConfig; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.connection.IConnectionRegistry; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.protocol.v1_0.LinkRegistry; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; @@ -41,7 +38,7 @@ import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.txn.DtxRegistry; -public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable, StatisticsGatherer +public interface VirtualHost extends DurableConfigurationStore.Source, Closeable, StatisticsGatherer { IConnectionRegistry getConnectionRegistry(); @@ -61,8 +58,6 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo void close(); - UUID getBrokerId(); - UUID getId(); void scheduleHouseKeepingTask(long period, HouseKeepingTask task); @@ -77,25 +72,12 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo int getHouseKeepingActiveCount(); - IApplicationRegistry getApplicationRegistry(); + VirtualHostRegistry getVirtualHostRegistry(); BindingFactory getBindingFactory(); - void createBrokerConnection(String transport, - String host, - int port, - String vhost, - boolean durable, - String authMechanism, String username, String password); - - public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments); - - ConfigStore getConfigStore(); - DtxRegistry getDtxRegistry(); - void removeBrokerConnection(BrokerLink brokerLink); - LinkRegistry getLinkRegistry(String remoteContainerId); ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask); diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java index ea2f0f15e4..ae88e3e9f7 100755 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java @@ -35,15 +35,16 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.binding.BindingFactory; import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.TransactionLogMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; import org.apache.qpid.server.message.AMQMessage; import org.apache.qpid.server.message.AbstractServerMessageImpl; import org.apache.qpid.server.message.EnqueableMessage; +import org.apache.qpid.server.message.MessageReference; import org.apache.qpid.server.message.MessageTransferMessage; import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.protocol.v1_0.Message_1_0; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.QueueEntry; @@ -65,7 +66,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa ConfigurationRecoveryHandler.QueueRecoveryHandler, ConfigurationRecoveryHandler.ExchangeRecoveryHandler, ConfigurationRecoveryHandler.BindingRecoveryHandler, - ConfigurationRecoveryHandler.BrokerLinkRecoveryHandler, MessageStoreRecoveryHandler, MessageStoreRecoveryHandler.StoredMessageRecoveryHandler, TransactionLogRecoveryHandler, @@ -77,7 +77,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa private final VirtualHost _virtualHost; private final Map<String, Integer> _queueRecoveries = new TreeMap<String, Integer>(); - private final Map<Long, AbstractServerMessageImpl> _recoveredMessages = new HashMap<Long, AbstractServerMessageImpl>(); + private final Map<Long, ServerMessage> _recoveredMessages = new HashMap<Long, ServerMessage>(); private final Map<Long, StoredMessage> _unusedMessages = new HashMap<Long, StoredMessage>(); private MessageStoreLogSubject _logSubject; @@ -169,7 +169,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa public void message(StoredMessage message) { - AbstractServerMessageImpl serverMessage; + ServerMessage serverMessage; switch(message.getMetaData().getType()) { case META_DATA_0_8: @@ -178,6 +178,9 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa case META_DATA_0_10: serverMessage = new MessageTransferMessage(message, null); break; + case META_DATA_1_0: + serverMessage = new Message_1_0(message); + break; default: throw new RuntimeException("Unknown message type retrieved from store " + message.getMetaData().getClass()); } @@ -190,19 +193,6 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa { } - public BridgeRecoveryHandler brokerLink(final UUID id, - final long createTime, - final Map<String, String> arguments) - { - BrokerLink blink = _virtualHost.createBrokerConnection(id, createTime, arguments); - return new BridgeRecoveryHandlerImpl(blink); - - } - - public void completeBrokerLinkRecovery() - { - } - public void dtxRecord(long format, byte[] globalId, byte[] branchId, Transaction.Record[] enqueues, Transaction.Record[] dequeues) @@ -221,12 +211,13 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa if(queue != null) { final long messageId = record.getMessage().getMessageNumber(); - final AbstractServerMessageImpl message = _recoveredMessages.get(messageId); + final ServerMessage message = _recoveredMessages.get(messageId); _unusedMessages.remove(messageId); if(message != null) { - message.incrementReference(); + final MessageReference ref = message.newReference(); + branch.enqueue(queue,message); @@ -239,7 +230,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa { queue.enqueue(message, true, null); - message.decrementReference(); + ref.release(); } catch (AMQException e) { @@ -251,7 +242,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa public void onRollback() { - message.decrementReference(); + ref.release(); } }); } @@ -280,7 +271,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa if(queue != null) { final long messageId = record.getMessage().getMessageNumber(); - final AbstractServerMessageImpl message = _recoveredMessages.get(messageId); + final ServerMessage message = _recoveredMessages.get(messageId); _unusedMessages.remove(messageId); if(message != null) @@ -412,9 +403,8 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa } - public BrokerLinkRecoveryHandler completeBindingRecovery() + public void completeBindingRecovery() { - return this; } public void complete() @@ -529,22 +519,4 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa } } - private class BridgeRecoveryHandlerImpl implements BridgeRecoveryHandler - { - private final BrokerLink _blink; - - public BridgeRecoveryHandlerImpl(final BrokerLink blink) - { - _blink = blink; - } - - public void bridge(final UUID id, final long createTime, final Map<String, String> arguments) - { - _blink.createBridge(id, createTime, arguments); - } - - public void completeBridgeRecoveryForLink() - { - } - } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java index d9dc0aa64e..dd3610373f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -35,12 +34,8 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.binding.BindingFactory; -import org.apache.qpid.server.configuration.BrokerConfig; -import org.apache.qpid.server.configuration.ConfigStore; -import org.apache.qpid.server.configuration.ConfiguredObject; import org.apache.qpid.server.configuration.ExchangeConfiguration; import org.apache.qpid.server.configuration.QueueConfiguration; -import org.apache.qpid.server.configuration.VirtualHostConfigType; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.connection.ConnectionRegistry; import org.apache.qpid.server.connection.IConnectionRegistry; @@ -49,7 +44,6 @@ import org.apache.qpid.server.exchange.DefaultExchangeRegistry; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; @@ -61,17 +55,16 @@ import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.queue.AMQQueueFactory; import org.apache.qpid.server.queue.DefaultQueueRegistry; import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.stats.StatisticsCounter; +import org.apache.qpid.server.stats.StatisticsGatherer; import org.apache.qpid.server.store.Event; import org.apache.qpid.server.store.EventListener; import org.apache.qpid.server.store.HAMessageStore; import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.MessageStoreCreator; import org.apache.qpid.server.store.OperationalLoggingListener; import org.apache.qpid.server.txn.DtxRegistry; -import org.apache.qpid.server.virtualhost.plugins.VirtualHostPlugin; -import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory; public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.RegistryChangeListener, EventListener { @@ -79,23 +72,19 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr private static final int HOUSEKEEPING_SHUTDOWN_TIMEOUT = 5; - private final UUID _qmfId; - private final String _name; private final UUID _id; private final long _createTime = System.currentTimeMillis(); - private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>(); - private final ScheduledThreadPoolExecutor _houseKeepingTasks; - private final IApplicationRegistry _appRegistry; + private final VirtualHostRegistry _virtualHostRegistry; - private final SecurityManager _securityManager; + private final StatisticsGatherer _brokerStatisticsGatherer; - private final BrokerConfig _brokerConfig; + private final SecurityManager _securityManager; private final VirtualHostConfiguration _vhostConfig; @@ -120,7 +109,7 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>(); private boolean _blocked; - public VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig) throws Exception + public VirtualHostImpl(VirtualHostRegistry virtualHostRegistry, StatisticsGatherer brokerStatisticsGatherer, SecurityManager parentSecurityManager, VirtualHostConfiguration hostConfig) throws Exception { if (hostConfig == null) { @@ -132,19 +121,17 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr throw new IllegalArgumentException("Illegal name (" + hostConfig.getName() + ") for virtualhost."); } - _appRegistry = appRegistry; - _brokerConfig = _appRegistry.getBrokerConfig(); + _virtualHostRegistry = virtualHostRegistry; + _brokerStatisticsGatherer = brokerStatisticsGatherer; _vhostConfig = hostConfig; _name = _vhostConfig.getName(); _dtxRegistry = new DtxRegistry(); - _qmfId = _appRegistry.getConfigStore().createId(); _id = UUIDGenerator.generateVhostUUID(_name); CurrentActor.get().message(VirtualHostMessages.CREATED(_name)); - _securityManager = new SecurityManager(_appRegistry.getSecurityManager()); - _securityManager.configureHostPlugins(_vhostConfig); + _securityManager = new SecurityManager(parentSecurityManager, _vhostConfig.getConfig().getString("security.acl")); _connectionRegistry = new ConnectionRegistry(); _connectionRegistry.addRegistryChangeListener(this); @@ -154,13 +141,12 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr _queueRegistry = new DefaultQueueRegistry(this); _exchangeFactory = new DefaultExchangeFactory(this); - _exchangeFactory.initialise(_vhostConfig); _exchangeRegistry = new DefaultExchangeRegistry(this); _bindingFactory = new BindingFactory(this); - _messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass()); + _messageStore = initialiseMessageStore(hostConfig); configureMessageStore(hostConfig); @@ -187,22 +173,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr return _id; } - @Override - public UUID getQMFId() - { - return _qmfId; - } - - public VirtualHostConfigType getConfigType() - { - return VirtualHostConfigType.getInstance(); - } - - public ConfiguredObject getParent() - { - return getBroker(); - } - public boolean isDurable() { return false; @@ -216,38 +186,9 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr */ private void initialiseHouseKeeping(long period) { - if (period != 0L) { scheduleHouseKeepingTask(period, new VirtualHostHouseKeepingTask()); - - Map<String, VirtualHostPluginFactory> plugins = _appRegistry.getPluginManager().getVirtualHostPlugins(); - - if (plugins != null) - { - for (Map.Entry<String, VirtualHostPluginFactory> entry : plugins.entrySet()) - { - String pluginName = entry.getKey(); - VirtualHostPluginFactory factory = entry.getValue(); - try - { - VirtualHostPlugin plugin = factory.newInstance(this); - - // If we had configuration for the plugin the schedule it. - if (plugin != null) - { - _houseKeepingTasks.scheduleAtFixedRate(plugin, plugin.getDelay() / 2, - plugin.getDelay(), plugin.getTimeUnit()); - - _logger.info("Loaded VirtualHostPlugin:" + plugin); - } - } - catch (RuntimeException e) - { - _logger.error("Unable to load VirtualHostPlugin:" + pluginName + " due to:" + e.getMessage(), e); - } - } - } } } @@ -329,19 +270,34 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr if (!(o instanceof MessageStore)) { - throw new ClassCastException("Message store factory class must implement " + MessageStore.class + + throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz + " does not."); } final MessageStore messageStore = (MessageStore) o; - final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, clazz.getSimpleName()); + return messageStore; + } + + private MessageStore initialiseMessageStore(VirtualHostConfiguration hostConfig) throws Exception + { + String storeType = hostConfig.getConfig().getString("store.type"); + MessageStore messageStore = null; + if (storeType == null) + { + messageStore = initialiseMessageStore(hostConfig.getMessageStoreClass()); + } + else + { + messageStore = new MessageStoreCreator().createMessageStore(storeType); + } + + final MessageStoreLogSubject storeLogSubject = new MessageStoreLogSubject(this, messageStore.getClass().getSimpleName()); OperationalLoggingListener.listen(messageStore, storeLogSubject); messageStore.addEventListener(new BeforeActivationListener(), Event.BEFORE_ACTIVATE); messageStore.addEventListener(new AfterActivationListener(), Event.AFTER_ACTIVATE); messageStore.addEventListener(new BeforeCloseListener(), Event.BEFORE_CLOSE); messageStore.addEventListener(new BeforePassivationListener(), Event.BEFORE_PASSIVATE); - return messageStore; } @@ -468,16 +424,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr return _name; } - public BrokerConfig getBroker() - { - return _brokerConfig; - } - - public String getFederationTag() - { - return _brokerConfig.getFederationTag(); - } - public long getCreateTime() { return _createTime; @@ -534,14 +480,9 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr CurrentActor.get().message(VirtualHostMessages.CLOSED()); } - public UUID getBrokerId() - { - return _appRegistry.getBrokerId(); - } - - public IApplicationRegistry getApplicationRegistry() + public VirtualHostRegistry getVirtualHostRegistry() { - return _appRegistry; + return _virtualHostRegistry; } public BindingFactory getBindingFactory() @@ -553,14 +494,14 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr { _messagesDelivered.registerEvent(1L); _dataDelivered.registerEvent(messageSize); - _appRegistry.registerMessageDelivered(messageSize); + _brokerStatisticsGatherer.registerMessageDelivered(messageSize); } public void registerMessageReceived(long messageSize, long timestamp) { _messagesReceived.registerEvent(1L, timestamp); _dataReceived.registerEvent(messageSize, timestamp); - _appRegistry.registerMessageReceived(messageSize, timestamp); + _brokerStatisticsGatherer.registerMessageReceived(messageSize, timestamp); } public StatisticsCounter getMessageReceiptStatistics() @@ -604,51 +545,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr _dataReceived = new StatisticsCounter("bytes-received-" + getName()); } - public BrokerLink createBrokerConnection(UUID id, long createTime, Map<String,String> arguments) - { - BrokerLink blink = new BrokerLink(this, id, createTime, arguments); - // TODO - cope with duplicate broker link creation requests - _links.putIfAbsent(blink,blink); - getConfigStore().addConfiguredObject(blink); - return blink; - } - - public void createBrokerConnection(final String transport, - final String host, - final int port, - final String vhost, - final boolean durable, - final String authMechanism, - final String username, - final String password) - { - BrokerLink blink = new BrokerLink(this, transport, host, port, vhost, durable, authMechanism, username, password); - - // TODO - cope with duplicate broker link creation requests - _links.putIfAbsent(blink,blink); - getConfigStore().addConfiguredObject(blink); - - } - - public void removeBrokerConnection(final String transport, - final String host, - final int port, - final String vhost) - { - removeBrokerConnection(new BrokerLink(this, transport, host, port, vhost, false, null,null,null)); - - } - - public void removeBrokerConnection(BrokerLink blink) - { - blink = _links.get(blink); - if(blink != null) - { - blink.close(); - getConfigStore().removeConfiguredObject(blink); - } - } - public synchronized LinkRegistry getLinkRegistry(String remoteContainerId) { LinkRegistry linkRegistry = _linkRegistry.get(remoteContainerId); @@ -660,11 +556,6 @@ public class VirtualHostImpl implements VirtualHost, IConnectionRegistry.Registr return linkRegistry; } - public ConfigStore getConfigStore() - { - return getApplicationRegistry().getConfigStore(); - } - public DtxRegistry getDtxRegistry() { return _dtxRegistry; diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java index 1be472844a..483e11942b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostRegistry.java @@ -1,140 +1,95 @@ -/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.virtualhost;
-
-import org.apache.qpid.common.Closeable;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections; -import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-
-public class VirtualHostRegistry implements Closeable
-{
- private final Map<String, VirtualHost> _registry = new ConcurrentHashMap<String, VirtualHost>();
-
-
- private String _defaultVirtualHostName;
- private ApplicationRegistry _applicationRegistry;
- private final Collection<RegistryChangeListener> _listeners = - Collections.synchronizedCollection(new ArrayList<RegistryChangeListener>()); -
- public VirtualHostRegistry(ApplicationRegistry applicationRegistry)
- {
- _applicationRegistry = applicationRegistry;
- }
-
- public synchronized void registerVirtualHost(VirtualHost host) throws Exception
- {
- if(_registry.containsKey(host.getName()))
- {
- throw new Exception("Virtual Host with name " + host.getName() + " already registered.");
- }
- _registry.put(host.getName(),host);
- synchronized (_listeners) +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhost; + +import org.apache.qpid.common.Closeable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public class VirtualHostRegistry implements Closeable +{ + private final Map<String, VirtualHost> _registry = new ConcurrentHashMap<String, VirtualHost>(); + private String _defaultVirtualHostName; + + + public VirtualHostRegistry() + { + super(); + } + + public synchronized void registerVirtualHost(VirtualHost host) + { + if(_registry.containsKey(host.getName())) { - for(RegistryChangeListener listener : _listeners) - { - listener.virtualHostRegistered(host); - } + throw new IllegalArgumentException("Virtual Host with name " + host.getName() + " already registered."); } - }
-
- public synchronized void unregisterVirtualHost(VirtualHost host)
- {
- _registry.remove(host.getName());
- synchronized (_listeners) + _registry.put(host.getName(),host); + } + + public synchronized void unregisterVirtualHost(VirtualHost host) + { + _registry.remove(host.getName()); + } + + public VirtualHost getVirtualHost(String name) + { + if(name == null || name.trim().length() == 0 || "/".equals(name.trim())) { - for(RegistryChangeListener listener : _listeners) - { - listener.virtualHostUnregistered(host); - } + name = getDefaultVirtualHostName(); } - }
-
- public VirtualHost getVirtualHost(String name)
- {
- if(name == null || name.trim().length() == 0 || "/".equals(name.trim()))
- {
- name = getDefaultVirtualHostName();
- }
-
- return _registry.get(name);
- }
-
- public VirtualHost getDefaultVirtualHost()
- {
- return getVirtualHost(getDefaultVirtualHostName());
- }
-
- private String getDefaultVirtualHostName()
- {
- return _defaultVirtualHostName;
- }
-
- public void setDefaultVirtualHostName(String defaultVirtualHostName)
- {
- _defaultVirtualHostName = defaultVirtualHostName;
- }
-
-
- public Collection<VirtualHost> getVirtualHosts()
- {
- return new ArrayList<VirtualHost>(_registry.values());
- }
-
- public ApplicationRegistry getApplicationRegistry()
- {
- return _applicationRegistry;
- }
-
- public ConfigStore getConfigStore()
- {
- return _applicationRegistry.getConfigStore();
- }
-
- public void close()
- {
- for (VirtualHost virtualHost : getVirtualHosts())
- {
- virtualHost.close();
- }
-
- }
- - public static interface RegistryChangeListener + + return _registry.get(name); + } + + public VirtualHost getDefaultVirtualHost() { - void virtualHostRegistered(VirtualHost virtualHost); - void virtualHostUnregistered(VirtualHost virtualHost); + return getVirtualHost(getDefaultVirtualHostName()); + } + private String getDefaultVirtualHostName() + { + return _defaultVirtualHostName; } - public void addRegistryChangeListener(RegistryChangeListener listener) + public void setDefaultVirtualHostName(String defaultVirtualHostName) { - _listeners.add(listener); + _defaultVirtualHostName = defaultVirtualHostName; + } + + + public Collection<VirtualHost> getVirtualHosts() + { + return new ArrayList<VirtualHost>(_registry.values()); + } + + public void close() + { + for (VirtualHost virtualHost : getVirtualHosts()) + { + virtualHost.close(); + } } -}
+} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java deleted file mode 100644 index 12886f400a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/ConfiguredQueueBindingListener.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost.plugins; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.exchange.Exchange.BindingListener; -import org.apache.qpid.server.queue.AMQQueue; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * This is a listener that caches queues that are configured for slow consumer disconnection. - * - * There should be one listener per virtual host, which can be added to all exchanges on - * that host. - * - * TODO In future, it will be possible to configure the policy at runtime, so only the queue - * itself is cached, and the configuration looked up by the housekeeping thread. This means - * that there may be occasions where the copy of the cache contents retrieved by the thread - * does not contain queues that are configured, or that configured queues are not present. - * - * @see BindingListener - */ -public class ConfiguredQueueBindingListener implements BindingListener -{ - private static final Logger _log = Logger.getLogger(ConfiguredQueueBindingListener.class); - - private String _vhostName; - private Set<AMQQueue> _cache = Collections.synchronizedSet(new HashSet<AMQQueue>()); - - public ConfiguredQueueBindingListener(String vhostName) - { - _vhostName = vhostName; - } - - /** - * @see BindingListener#bindingAdded(Exchange, Binding) - */ - public void bindingAdded(Exchange exchange, Binding binding) - { - processBinding(binding); - } - - /** - * @see BindingListener#bindingRemoved(Exchange, Binding) - */ - public void bindingRemoved(Exchange exchange, Binding binding) - { - processBinding(binding); - } - - private void processBinding(Binding binding) - { - AMQQueue queue = binding.getQueue(); - - SlowConsumerDetectionQueueConfiguration config = - queue.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName()); - if (config != null) - { - _cache.add(queue); - } - else - { - _cache.remove(queue); - } - } - - /** - * Lookup and return the cache of configured {@link AMQQueue}s. - * - * Note that when accessing the cached queues, the {@link java.util.Iterator} is not thread safe - * (see the {@link Collections#synchronizedSet(Set)} documentation) so a copy of the - * cache is returned. - * - * @return a copy of the cached {@link java.util.Set} of queues - */ - public Set<AMQQueue> getQueueCache() - { - return new HashSet<AMQQueue>(_cache); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java deleted file mode 100644 index bd2e30449a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/SlowConsumerDetection.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost.plugins; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration; -import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.virtualhost.VirtualHost; -import org.apache.qpid.server.virtualhost.plugins.logging.SlowConsumerDetectionMessages; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; - -import java.util.Set; -import java.util.concurrent.TimeUnit; - -public class SlowConsumerDetection extends VirtualHostHouseKeepingPlugin -{ - private SlowConsumerDetectionConfiguration _config; - private ConfiguredQueueBindingListener _listener; - - public static class SlowConsumerFactory implements VirtualHostPluginFactory - { - public SlowConsumerDetection newInstance(VirtualHost vhost) - { - SlowConsumerDetectionConfiguration config = vhost.getConfiguration().getConfiguration(SlowConsumerDetectionConfiguration.class.getName()); - - if (config == null) - { - return null; - } - - SlowConsumerDetection plugin = new SlowConsumerDetection(vhost); - plugin.configure(config); - return plugin; - } - } - - /** - * Configures the slow consumer disconnect plugin by adding a listener to each exchange on this - * virtual host to record all the configured queues in a cache for processing by the housekeeping - * thread. - * - * @see org.apache.qpid.server.plugins.Plugin#configure(ConfigurationPlugin) - */ - public void configure(ConfigurationPlugin config) - { - _config = (SlowConsumerDetectionConfiguration) config; - _listener = new ConfiguredQueueBindingListener(getVirtualHost().getName()); - final ExchangeRegistry exchangeRegistry = getVirtualHost().getExchangeRegistry(); - for (AMQShortString exchangeName : exchangeRegistry.getExchangeNames()) - { - exchangeRegistry.getExchange(exchangeName).addBindingListener(_listener); - } - } - - public SlowConsumerDetection(VirtualHost vhost) - { - super(vhost); - } - - public void execute() - { - CurrentActor.get().message(SlowConsumerDetectionMessages.RUNNING()); - - Set<AMQQueue> cache = _listener.getQueueCache(); - for (AMQQueue q : cache) - { - CurrentActor.get().message(SlowConsumerDetectionMessages.CHECKING_QUEUE(q.getName())); - - try - { - final SlowConsumerDetectionQueueConfiguration config = - q.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName()); - if (checkQueueStatus(q, config)) - { - final SlowConsumerPolicyPlugin policy = config.getPolicy(); - if (policy == null) - { - // We would only expect to see this during shutdown - getLogger().warn("No slow consumer policy for queue " + q.getName()); - } - else - { - policy.performPolicy(q); - } - - } - } - catch (Exception e) - { - // Don't throw exceptions as this will stop the house keeping task from running. - getLogger().error("Exception in SlowConsumersDetection for queue: " + q.getName(), e); - } - } - - CurrentActor.get().message(SlowConsumerDetectionMessages.COMPLETE()); - } - - public long getDelay() - { - return _config.getDelay(); - } - - public TimeUnit getTimeUnit() - { - return _config.getTimeUnit(); - } - - /** - * Check the depth,messageSize,messageAge,messageCount values for this q - * - * @param q the queue to check - * @param config the queue configuration to compare against the queue state - * - * @return true if the queue has reached a threshold. - */ - private boolean checkQueueStatus(AMQQueue q, SlowConsumerDetectionQueueConfiguration config) - { - if (config != null) - { - if (getLogger().isInfoEnabled()) - { - getLogger().info("Retrieved Queue(" + q.getName() + ") Config:" + config); - } - - int count = q.getMessageCount(); - - // First Check message counts - if ((config.getMessageCount() != 0 && count >= config.getMessageCount()) || - // The check queue depth - (config.getDepth() != 0 && q.getQueueDepth() >= config.getDepth()) || - // finally if we have messages on the queue check Arrival time. - // We must check count as OldestArrival time is Long.MAX_LONG when - // there are no messages. - (config.getMessageAge() != 0 && - ((count > 0) && q.getOldestMessageArrivalTime() >= config.getMessageAge()))) - { - - if (getLogger().isDebugEnabled()) - { - getLogger().debug("Detected Slow Consumer on Queue(" + q.getName() + ")"); - getLogger().debug("Queue Count:" + q.getMessageCount() + ":" + config.getMessageCount()); - getLogger().debug("Queue Depth:" + q.getQueueDepth() + ":" + config.getDepth()); - getLogger().debug("Queue Arrival:" + q.getOldestMessageArrivalTime() + ":" + config.getMessageAge()); - } - - return true; - } - } - return false; - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java deleted file mode 100644 index 35f6228ab9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost.plugins; - -import org.apache.qpid.server.plugins.Plugin; - -import java.util.concurrent.TimeUnit; - -public interface VirtualHostPlugin extends Runnable, Plugin -{ - /** - * Long value representing the delay between repeats - * - * @return - */ - public long getDelay(); - - /** - * Option to specify what the delay value represents - * @see java.util.concurrent.TimeUnit for valid value. - * @return - */ - public TimeUnit getTimeUnit(); -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java deleted file mode 100644 index c8bea18444..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPluginFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost.plugins; - -import org.apache.qpid.server.virtualhost.VirtualHost; - -public interface VirtualHostPluginFactory -{ - public VirtualHostHouseKeepingPlugin newInstance(VirtualHost vhost); -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties deleted file mode 100644 index 03c56910c2..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/SlowConsumerDetection_logmessages.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -# Default File used for all non-defined locales. - -RUNNING = SCD-1001 : Running -COMPLETE = SCD-1002 : Complete -CHECKING_QUEUE = SCD-1003 : Checking Status of Queue {0}
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties deleted file mode 100644 index ed4fb1d45a..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/logging/TopicDeletePolicy_logmessages.properties +++ /dev/null @@ -1,22 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -# Default File used for all non-defined locales. - -DELETING_QUEUE = TDP-1001 : Deleting Queue -DISCONNECTING = TDP-1002 : Disconnecting Session
\ No newline at end of file diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java deleted file mode 100644 index f2f61f204e..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicy.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost.plugins.policies; - -import org.apache.commons.configuration.ConfigurationException; -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.server.binding.Binding; -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.logging.actors.CurrentActor; -import org.apache.qpid.server.protocol.AMQSessionModel; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.virtualhost.plugins.logging.TopicDeletePolicyMessages; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPlugin; -import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory; - -public class TopicDeletePolicy implements SlowConsumerPolicyPlugin -{ - private Logger _logger = Logger.getLogger(TopicDeletePolicy.class); - private TopicDeletePolicyConfiguration _configuration; - - public static class TopicDeletePolicyFactory implements SlowConsumerPolicyPluginFactory - { - public TopicDeletePolicy newInstance(ConfigurationPlugin configuration) throws ConfigurationException - { - TopicDeletePolicyConfiguration config = - configuration.getConfiguration(TopicDeletePolicyConfiguration.class.getName()); - - TopicDeletePolicy policy = new TopicDeletePolicy(); - policy.configure(config); - return policy; - } - - public String getPluginName() - { - return "topicdelete"; - } - - public Class<TopicDeletePolicy> getPluginClass() - { - return TopicDeletePolicy.class; - } - } - - public void performPolicy(AMQQueue q) - { - if (q == null) - { - return; - } - - AMQSessionModel owner = q.getExclusiveOwningSession(); - - // Only process exclusive queues - if (owner == null) - { - return; - } - - //Only process Topics - if (!validateQueueIsATopic(q)) - { - return; - } - - try - { - CurrentActor.get().message(owner.getLogSubject(),TopicDeletePolicyMessages.DISCONNECTING()); - // Close the consumer . this will cause autoDelete Queues to be purged - owner.getConnectionModel(). - closeSession(owner, AMQConstant.RESOURCE_ERROR, - "Consuming to slow."); - - // Actively delete non autoDelete queues if deletePersistent is set - if (!q.isAutoDelete() && (_configuration != null && _configuration.deletePersistent())) - { - CurrentActor.get().message(q.getLogSubject(), TopicDeletePolicyMessages.DELETING_QUEUE()); - q.delete(); - } - - } - catch (AMQException e) - { - _logger.warn("Unable to close consumer:" + owner + ", on queue:" + q.getName()); - } - - } - - /** - * Check the queue bindings to validate the queue is bound to the - * topic exchange. - * - * @param q the Queue - * - * @return true iff Q is bound to a TopicExchange - */ - private boolean validateQueueIsATopic(AMQQueue q) - { - for (Binding binding : q.getBindings()) - { - if (binding.getExchange() instanceof TopicExchange) - { - return true; - } - } - - return false; - } - - public void configure(ConfigurationPlugin config) - { - _configuration = (TopicDeletePolicyConfiguration) config; - } - - @Override - public String toString() - { - return "TopicDelete" + (_configuration == null ? "" : "[" + _configuration + "]"); - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java deleted file mode 100644 index 48158b7dff..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/policies/TopicDeletePolicyConfiguration.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.virtualhost.plugins.policies; - -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; -import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; - -import java.util.Arrays; -import java.util.List; - -public class TopicDeletePolicyConfiguration extends ConfigurationPlugin -{ - - public static class TopicDeletePolicyConfigurationFactory - implements ConfigurationPluginFactory - { - public ConfigurationPlugin newInstance(String path, - Configuration config) - throws ConfigurationException - { - TopicDeletePolicyConfiguration slowConsumerConfig = - new TopicDeletePolicyConfiguration(); - slowConsumerConfig.setConfiguration(path, config); - return slowConsumerConfig; - } - - public List<String> getParentPaths() - { - return Arrays.asList( - "virtualhosts.virtualhost.queues.slow-consumer-detection.policy.topicDelete", - "virtualhosts.virtualhost.queues.queue.slow-consumer-detection.policy.topicDelete", - "virtualhosts.virtualhost.topics.slow-consumer-detection.policy.topicDelete", - "virtualhosts.virtualhost.topics.topic.slow-consumer-detection.policy.topicDelete"); - } - } - - public String[] getElementsProcessed() - { - return new String[]{"delete-persistent"}; - } - - @Override - public void validateConfiguration() throws ConfigurationException - { - // No validation required. - } - - public boolean deletePersistent() - { - // If we don't have configuration then we don't deletePersistent Queues - return (hasConfiguration() && contains("delete-persistent")); - } - - @Override - public String formatToString() - { - return (deletePersistent()?"delete-durable":""); - } - - -} diff --git a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java b/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java deleted file mode 100644 index 7f600abdc9..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPlugin.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.slowconsumerdetection.policies; - -import org.apache.qpid.server.plugins.Plugin; -import org.apache.qpid.server.queue.AMQQueue; - -public interface SlowConsumerPolicyPlugin extends Plugin -{ - public void performPolicy(AMQQueue Queue); -} diff --git a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java deleted file mode 100644 index b2fe6766a6..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/slowconsumerdetection/policies/SlowConsumerPolicyPluginFactory.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.slowconsumerdetection.policies; - -import org.apache.qpid.server.plugins.PluginFactory; - -public interface SlowConsumerPolicyPluginFactory<P extends SlowConsumerPolicyPlugin> extends PluginFactory<P> -{ -} diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory new file mode 100644 index 0000000000..5f75a8c4c9 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.configuration.ConfigurationStoreFactory @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.configuration.store.factory.JsonConfigurationStoreFactory diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory new file mode 100644 index 0000000000..8ff67030ef --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.AuthenticationManagerFactory @@ -0,0 +1,24 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory +org.apache.qpid.server.security.auth.manager.SimpleLDAPAuthenticationManagerFactory diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType new file mode 100644 index 0000000000..4ad646b7a0 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ExchangeType @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.exchange.DirectExchangeType +org.apache.qpid.server.exchange.TopicExchangeType +org.apache.qpid.server.exchange.FanoutExchangeType +org.apache.qpid.server.exchange.HeadersExchangeType diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory new file mode 100644 index 0000000000..6bfb55ff18 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.GroupManagerFactory @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.security.group.FileGroupManagerFactory diff --git a/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory new file mode 100644 index 0000000000..1357f816b7 --- /dev/null +++ b/java/broker/src/main/resources/META-INF/services/org.apache.qpid.server.store.MessageStoreFactory @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.store.derby.DerbyMessageStoreFactory +org.apache.qpid.server.store.MemoryMessageStoreFactory
\ No newline at end of file diff --git a/java/broker/src/main/resources/initial-store.json b/java/broker/src/main/resources/initial-store.json new file mode 100644 index 0000000000..a80ad95bd4 --- /dev/null +++ b/java/broker/src/main/resources/initial-store.json @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +{ + "name": "QpidBroker", + "defaultAuthenticationProvider" : "defaultAuthenticationProvider", + "defaultVirtualHost" : "default", + "authenticationproviders" : [ { + "name" : "defaultAuthenticationProvider", + "authenticationProviderType" : "PlainPasswordFileAuthenticationProvider", + "path" : "${QPID_HOME}/etc/passwd" + } ], + "ports" : [ { + "name" : "5672-AMQP", + "port" : 5672 + }, { + "name" : "8080-HTTP", + "port" : 8080, + "protocols" : [ "HTTP" ] + }, { + "name" : "8999-RMI", + "port" : 8999, + "protocols" : [ "RMI" ] + }, { + "name" : "9099-JMX_RMI", + "port" : 9099, + "protocols" : [ "JMX_RMI" ] + }], + "virtualhosts" : [ { + "name" : "default", + "storeType" : "DERBY", + "storePath" : "${QPID_WORK}/store" + } ], + "plugins" : [ { + "pluginType" : "MANAGEMENT-HTTP", + "name" : "httpManagement" + }, { + "pluginType" : "MANAGEMENT-JMX", + "name" : "jmxManagement" + } ] +}
\ No newline at end of file |