summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/broker
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid/broker')
-rw-r--r--cpp/src/qpid/broker/AclModule.h281
-rw-r--r--cpp/src/qpid/broker/AsyncCompletion.h201
-rw-r--r--cpp/src/qpid/broker/Bridge.cpp323
-rw-r--r--cpp/src/qpid/broker/Bridge.h111
-rw-r--r--cpp/src/qpid/broker/Broker.cpp967
-rw-r--r--cpp/src/qpid/broker/Broker.h351
-rw-r--r--cpp/src/qpid/broker/BrokerImportExport.h42
-rw-r--r--cpp/src/qpid/broker/Connection.cpp487
-rw-r--r--cpp/src/qpid/broker/Connection.h216
-rw-r--r--cpp/src/qpid/broker/ConnectionFactory.cpp66
-rw-r--r--cpp/src/qpid/broker/ConnectionFactory.h51
-rw-r--r--cpp/src/qpid/broker/ConnectionHandler.cpp364
-rw-r--r--cpp/src/qpid/broker/ConnectionHandler.h112
-rw-r--r--cpp/src/qpid/broker/ConnectionState.h117
-rw-r--r--cpp/src/qpid/broker/ConnectionToken.h40
-rw-r--r--cpp/src/qpid/broker/Consumer.h58
-rw-r--r--cpp/src/qpid/broker/Daemon.cpp219
-rw-r--r--cpp/src/qpid/broker/Daemon.h84
-rw-r--r--cpp/src/qpid/broker/Deliverable.h43
-rw-r--r--cpp/src/qpid/broker/DeliverableMessage.cpp45
-rw-r--r--cpp/src/qpid/broker/DeliverableMessage.h45
-rw-r--r--cpp/src/qpid/broker/DeliveryAdapter.h53
-rw-r--r--cpp/src/qpid/broker/DeliveryId.h35
-rw-r--r--cpp/src/qpid/broker/DeliveryRecord.cpp196
-rw-r--r--cpp/src/qpid/broker/DeliveryRecord.h143
-rw-r--r--cpp/src/qpid/broker/DirectExchange.cpp194
-rw-r--r--cpp/src/qpid/broker/DirectExchange.h74
-rw-r--r--cpp/src/qpid/broker/DtxAck.cpp73
-rw-r--r--cpp/src/qpid/broker/DtxAck.h48
-rw-r--r--cpp/src/qpid/broker/DtxBuffer.cpp83
-rw-r--r--cpp/src/qpid/broker/DtxBuffer.h57
-rw-r--r--cpp/src/qpid/broker/DtxManager.cpp171
-rw-r--r--cpp/src/qpid/broker/DtxManager.h74
-rw-r--r--cpp/src/qpid/broker/DtxTimeout.cpp35
-rw-r--r--cpp/src/qpid/broker/DtxTimeout.h48
-rw-r--r--cpp/src/qpid/broker/DtxWorkRecord.cpp177
-rw-r--r--cpp/src/qpid/broker/DtxWorkRecord.h81
-rw-r--r--cpp/src/qpid/broker/Exchange.cpp403
-rw-r--r--cpp/src/qpid/broker/Exchange.h248
-rw-r--r--cpp/src/qpid/broker/ExchangeRegistry.cpp116
-rw-r--r--cpp/src/qpid/broker/ExchangeRegistry.h93
-rw-r--r--cpp/src/qpid/broker/ExpiryPolicy.cpp38
-rw-r--r--cpp/src/qpid/broker/ExpiryPolicy.h46
-rw-r--r--cpp/src/qpid/broker/Fairshare.cpp186
-rw-r--r--cpp/src/qpid/broker/Fairshare.h61
-rw-r--r--cpp/src/qpid/broker/FanOutExchange.cpp119
-rw-r--r--cpp/src/qpid/broker/FanOutExchange.h74
-rw-r--r--cpp/src/qpid/broker/FedOps.h38
-rw-r--r--cpp/src/qpid/broker/HandlerImpl.h53
-rw-r--r--cpp/src/qpid/broker/HeadersExchange.cpp341
-rw-r--r--cpp/src/qpid/broker/HeadersExchange.h122
-rw-r--r--cpp/src/qpid/broker/LegacyLVQ.cpp116
-rw-r--r--cpp/src/qpid/broker/LegacyLVQ.h59
-rw-r--r--cpp/src/qpid/broker/Link.cpp474
-rw-r--r--cpp/src/qpid/broker/Link.h145
-rw-r--r--cpp/src/qpid/broker/LinkRegistry.cpp399
-rw-r--r--cpp/src/qpid/broker/LinkRegistry.h163
-rw-r--r--cpp/src/qpid/broker/Message.cpp452
-rw-r--r--cpp/src/qpid/broker/Message.h196
-rw-r--r--cpp/src/qpid/broker/MessageAdapter.cpp81
-rw-r--r--cpp/src/qpid/broker/MessageAdapter.h62
-rw-r--r--cpp/src/qpid/broker/MessageBuilder.cpp114
-rw-r--r--cpp/src/qpid/broker/MessageBuilder.h56
-rw-r--r--cpp/src/qpid/broker/MessageDeque.cpp140
-rw-r--r--cpp/src/qpid/broker/MessageDeque.h62
-rw-r--r--cpp/src/qpid/broker/MessageMap.cpp166
-rw-r--r--cpp/src/qpid/broker/MessageMap.h72
-rw-r--r--cpp/src/qpid/broker/MessageStore.h205
-rw-r--r--cpp/src/qpid/broker/MessageStoreModule.cpp180
-rw-r--r--cpp/src/qpid/broker/MessageStoreModule.h87
-rw-r--r--cpp/src/qpid/broker/Messages.h117
-rw-r--r--cpp/src/qpid/broker/NameGenerator.cpp32
-rw-r--r--cpp/src/qpid/broker/NameGenerator.h39
-rw-r--r--cpp/src/qpid/broker/NullMessageStore.cpp167
-rw-r--r--cpp/src/qpid/broker/NullMessageStore.h100
-rw-r--r--cpp/src/qpid/broker/OwnershipToken.h38
-rw-r--r--cpp/src/qpid/broker/Persistable.h63
-rw-r--r--cpp/src/qpid/broker/PersistableConfig.h45
-rw-r--r--cpp/src/qpid/broker/PersistableExchange.h45
-rw-r--r--cpp/src/qpid/broker/PersistableMessage.cpp161
-rw-r--r--cpp/src/qpid/broker/PersistableMessage.h143
-rw-r--r--cpp/src/qpid/broker/PersistableQueue.h78
-rw-r--r--cpp/src/qpid/broker/PriorityQueue.cpp212
-rw-r--r--cpp/src/qpid/broker/PriorityQueue.h78
-rw-r--r--cpp/src/qpid/broker/Queue.cpp1225
-rw-r--r--cpp/src/qpid/broker/Queue.h390
-rw-r--r--cpp/src/qpid/broker/QueueBindings.cpp47
-rw-r--r--cpp/src/qpid/broker/QueueBindings.h61
-rw-r--r--cpp/src/qpid/broker/QueueCleaner.cpp74
-rw-r--r--cpp/src/qpid/broker/QueueCleaner.h59
-rw-r--r--cpp/src/qpid/broker/QueueEvents.cpp147
-rw-r--r--cpp/src/qpid/broker/QueueEvents.h85
-rw-r--r--cpp/src/qpid/broker/QueueFlowLimit.cpp407
-rw-r--r--cpp/src/qpid/broker/QueueFlowLimit.h129
-rw-r--r--cpp/src/qpid/broker/QueueListeners.cpp98
-rw-r--r--cpp/src/qpid/broker/QueueListeners.h86
-rw-r--r--cpp/src/qpid/broker/QueueObserver.h42
-rw-r--r--cpp/src/qpid/broker/QueuePolicy.cpp360
-rw-r--r--cpp/src/qpid/broker/QueuePolicy.h123
-rw-r--r--cpp/src/qpid/broker/QueueRegistry.cpp127
-rw-r--r--cpp/src/qpid/broker/QueueRegistry.h151
-rw-r--r--cpp/src/qpid/broker/QueuedMessage.h48
-rw-r--r--cpp/src/qpid/broker/RateFlowcontrol.h105
-rw-r--r--cpp/src/qpid/broker/RateTracker.cpp51
-rw-r--r--cpp/src/qpid/broker/RateTracker.h57
-rw-r--r--cpp/src/qpid/broker/RecoverableConfig.h45
-rw-r--r--cpp/src/qpid/broker/RecoverableExchange.h52
-rw-r--r--cpp/src/qpid/broker/RecoverableMessage.h59
-rw-r--r--cpp/src/qpid/broker/RecoverableQueue.h59
-rw-r--r--cpp/src/qpid/broker/RecoverableTransaction.h49
-rw-r--r--cpp/src/qpid/broker/RecoveredDequeue.cpp48
-rw-r--r--cpp/src/qpid/broker/RecoveredDequeue.h56
-rw-r--r--cpp/src/qpid/broker/RecoveredEnqueue.cpp45
-rw-r--r--cpp/src/qpid/broker/RecoveredEnqueue.h57
-rw-r--r--cpp/src/qpid/broker/RecoveryManager.h61
-rw-r--r--cpp/src/qpid/broker/RecoveryManagerImpl.cpp278
-rw-r--r--cpp/src/qpid/broker/RecoveryManagerImpl.h58
-rw-r--r--cpp/src/qpid/broker/RetryList.cpp56
-rw-r--r--cpp/src/qpid/broker/RetryList.h54
-rw-r--r--cpp/src/qpid/broker/SaslAuthenticator.cpp467
-rw-r--r--cpp/src/qpid/broker/SaslAuthenticator.h64
-rw-r--r--cpp/src/qpid/broker/SecureConnection.cpp90
-rw-r--r--cpp/src/qpid/broker/SecureConnection.h60
-rw-r--r--cpp/src/qpid/broker/SecureConnectionFactory.cpp75
-rw-r--r--cpp/src/qpid/broker/SecureConnectionFactory.h49
-rw-r--r--cpp/src/qpid/broker/SemanticState.cpp823
-rw-r--r--cpp/src/qpid/broker/SemanticState.h257
-rw-r--r--cpp/src/qpid/broker/SessionAdapter.cpp693
-rw-r--r--cpp/src/qpid/broker/SessionAdapter.h273
-rw-r--r--cpp/src/qpid/broker/SessionContext.h56
-rw-r--r--cpp/src/qpid/broker/SessionHandler.cpp120
-rw-r--r--cpp/src/qpid/broker/SessionHandler.h99
-rw-r--r--cpp/src/qpid/broker/SessionManager.cpp104
-rw-r--r--cpp/src/qpid/broker/SessionManager.h87
-rw-r--r--cpp/src/qpid/broker/SessionOutputException.h47
-rw-r--r--cpp/src/qpid/broker/SessionState.cpp591
-rw-r--r--cpp/src/qpid/broker/SessionState.h284
-rw-r--r--cpp/src/qpid/broker/SignalHandler.cpp54
-rw-r--r--cpp/src/qpid/broker/SignalHandler.h50
-rw-r--r--cpp/src/qpid/broker/StatefulQueueObserver.h63
-rw-r--r--cpp/src/qpid/broker/System.cpp84
-rw-r--r--cpp/src/qpid/broker/System.h51
-rw-r--r--cpp/src/qpid/broker/ThresholdAlerts.cpp191
-rw-r--r--cpp/src/qpid/broker/ThresholdAlerts.h73
-rw-r--r--cpp/src/qpid/broker/TopicExchange.cpp692
-rw-r--r--cpp/src/qpid/broker/TopicExchange.h208
-rw-r--r--cpp/src/qpid/broker/TransactionalStore.h60
-rw-r--r--cpp/src/qpid/broker/TxAccept.cpp100
-rw-r--r--cpp/src/qpid/broker/TxAccept.h83
-rw-r--r--cpp/src/qpid/broker/TxBuffer.cpp80
-rw-r--r--cpp/src/qpid/broker/TxBuffer.h119
-rw-r--r--cpp/src/qpid/broker/TxOp.h46
-rw-r--r--cpp/src/qpid/broker/TxOpVisitor.h97
-rw-r--r--cpp/src/qpid/broker/TxPublish.cpp111
-rw-r--r--cpp/src/qpid/broker/TxPublish.h91
-rw-r--r--cpp/src/qpid/broker/Vhost.cpp49
-rw-r--r--cpp/src/qpid/broker/Vhost.h50
-rw-r--r--cpp/src/qpid/broker/posix/BrokerDefaults.cpp40
-rw-r--r--cpp/src/qpid/broker/windows/BrokerDefaults.cpp47
-rw-r--r--cpp/src/qpid/broker/windows/SaslAuthenticator.cpp193
-rw-r--r--cpp/src/qpid/broker/windows/SslProtocolFactory.cpp302
161 files changed, 0 insertions, 24272 deletions
diff --git a/cpp/src/qpid/broker/AclModule.h b/cpp/src/qpid/broker/AclModule.h
deleted file mode 100644
index 2f4f7eaacc..0000000000
--- a/cpp/src/qpid/broker/AclModule.h
+++ /dev/null
@@ -1,281 +0,0 @@
-#ifndef QPID_ACLMODULE_ACL_H
-#define QPID_ACLMODULE_ACL_H
-
-
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include "qpid/RefCounted.h"
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <set>
-#include <string>
-#include <sstream>
-
-namespace qpid {
-
-namespace acl {
-
-enum ObjectType {OBJ_QUEUE, OBJ_EXCHANGE, OBJ_BROKER, OBJ_LINK,
- OBJ_METHOD, OBJECTSIZE}; // OBJECTSIZE must be last in list
-enum Action {ACT_CONSUME, ACT_PUBLISH, ACT_CREATE, ACT_ACCESS, ACT_BIND,
- ACT_UNBIND, ACT_DELETE, ACT_PURGE, ACT_UPDATE,
- ACTIONSIZE}; // ACTIONSIZE must be last in list
-enum Property {PROP_NAME, PROP_DURABLE, PROP_OWNER, PROP_ROUTINGKEY,
- PROP_PASSIVE, PROP_AUTODELETE, PROP_EXCLUSIVE, PROP_TYPE,
- PROP_ALTERNATE, PROP_QUEUENAME, PROP_SCHEMAPACKAGE,
- PROP_SCHEMACLASS, PROP_POLICYTYPE, PROP_MAXQUEUESIZE,
- PROP_MAXQUEUECOUNT};
-enum AclResult {ALLOW, ALLOWLOG, DENY, DENYLOG};
-
-} // namespace acl
-
-namespace broker {
-
-
-class AclModule
-{
-
-public:
-
- // effienty turn off ACL on message transfer.
- virtual bool doTransferAcl()=0;
-
- virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& name,
- std::map<acl::Property, std::string>* params=0)=0;
- virtual bool authorise(const std::string& id, const acl::Action& action, const acl::ObjectType& objType, const std::string& ExchangeName,
- const std::string& RoutingKey)=0;
- // create specilied authorise methods for cases that need faster matching as needed.
-
- virtual ~AclModule() {};
-};
-
-} // namespace broker
-
-namespace acl {
-
-class AclHelper {
- private:
- AclHelper(){}
- public:
- static inline ObjectType getObjectType(const std::string& str) {
- if (str.compare("queue") == 0) return OBJ_QUEUE;
- if (str.compare("exchange") == 0) return OBJ_EXCHANGE;
- if (str.compare("broker") == 0) return OBJ_BROKER;
- if (str.compare("link") == 0) return OBJ_LINK;
- if (str.compare("method") == 0) return OBJ_METHOD;
- throw str;
- }
- static inline std::string getObjectTypeStr(const ObjectType o) {
- switch (o) {
- case OBJ_QUEUE: return "queue";
- case OBJ_EXCHANGE: return "exchange";
- case OBJ_BROKER: return "broker";
- case OBJ_LINK: return "link";
- case OBJ_METHOD: return "method";
- default: assert(false); // should never get here
- }
- return "";
- }
- static inline Action getAction(const std::string& str) {
- if (str.compare("consume") == 0) return ACT_CONSUME;
- if (str.compare("publish") == 0) return ACT_PUBLISH;
- if (str.compare("create") == 0) return ACT_CREATE;
- if (str.compare("access") == 0) return ACT_ACCESS;
- if (str.compare("bind") == 0) return ACT_BIND;
- if (str.compare("unbind") == 0) return ACT_UNBIND;
- if (str.compare("delete") == 0) return ACT_DELETE;
- if (str.compare("purge") == 0) return ACT_PURGE;
- if (str.compare("update") == 0) return ACT_UPDATE;
- throw str;
- }
- static inline std::string getActionStr(const Action a) {
- switch (a) {
- case ACT_CONSUME: return "consume";
- case ACT_PUBLISH: return "publish";
- case ACT_CREATE: return "create";
- case ACT_ACCESS: return "access";
- case ACT_BIND: return "bind";
- case ACT_UNBIND: return "unbind";
- case ACT_DELETE: return "delete";
- case ACT_PURGE: return "purge";
- case ACT_UPDATE: return "update";
- default: assert(false); // should never get here
- }
- return "";
- }
- static inline Property getProperty(const std::string& str) {
- if (str.compare("name") == 0) return PROP_NAME;
- if (str.compare("durable") == 0) return PROP_DURABLE;
- if (str.compare("owner") == 0) return PROP_OWNER;
- if (str.compare("routingkey") == 0) return PROP_ROUTINGKEY;
- if (str.compare("passive") == 0) return PROP_PASSIVE;
- if (str.compare("autodelete") == 0) return PROP_AUTODELETE;
- if (str.compare("exclusive") == 0) return PROP_EXCLUSIVE;
- if (str.compare("type") == 0) return PROP_TYPE;
- if (str.compare("alternate") == 0) return PROP_ALTERNATE;
- if (str.compare("queuename") == 0) return PROP_QUEUENAME;
- if (str.compare("schemapackage") == 0) return PROP_SCHEMAPACKAGE;
- if (str.compare("schemaclass") == 0) return PROP_SCHEMACLASS;
- if (str.compare("policytype") == 0) return PROP_POLICYTYPE;
- if (str.compare("maxqueuesize") == 0) return PROP_MAXQUEUESIZE;
- if (str.compare("maxqueuecount") == 0) return PROP_MAXQUEUECOUNT;
- throw str;
- }
- static inline std::string getPropertyStr(const Property p) {
- switch (p) {
- case PROP_NAME: return "name";
- case PROP_DURABLE: return "durable";
- case PROP_OWNER: return "owner";
- case PROP_ROUTINGKEY: return "routingkey";
- case PROP_PASSIVE: return "passive";
- case PROP_AUTODELETE: return "autodelete";
- case PROP_EXCLUSIVE: return "exclusive";
- case PROP_TYPE: return "type";
- case PROP_ALTERNATE: return "alternate";
- case PROP_QUEUENAME: return "queuename";
- case PROP_SCHEMAPACKAGE: return "schemapackage";
- case PROP_SCHEMACLASS: return "schemaclass";
- case PROP_POLICYTYPE: return "policytype";
- case PROP_MAXQUEUESIZE: return "maxqueuesize";
- case PROP_MAXQUEUECOUNT: return "maxqueuecount";
- default: assert(false); // should never get here
- }
- return "";
- }
- static inline AclResult getAclResult(const std::string& str) {
- if (str.compare("allow") == 0) return ALLOW;
- if (str.compare("allow-log") == 0) return ALLOWLOG;
- if (str.compare("deny") == 0) return DENY;
- if (str.compare("deny-log") == 0) return DENYLOG;
- throw str;
- }
- static inline std::string getAclResultStr(const AclResult r) {
- switch (r) {
- case ALLOW: return "allow";
- case ALLOWLOG: return "allow-log";
- case DENY: return "deny";
- case DENYLOG: return "deny-log";
- default: assert(false); // should never get here
- }
- return "";
- }
-
- typedef std::set<Property> propSet;
- typedef boost::shared_ptr<propSet> propSetPtr;
- typedef std::pair<Action, propSetPtr> actionPair;
- typedef std::map<Action, propSetPtr> actionMap;
- typedef boost::shared_ptr<actionMap> actionMapPtr;
- typedef std::pair<ObjectType, actionMapPtr> objectPair;
- typedef std::map<ObjectType, actionMapPtr> objectMap;
- typedef objectMap::const_iterator omCitr;
- typedef boost::shared_ptr<objectMap> objectMapPtr;
- typedef std::map<Property, std::string> propMap;
- typedef propMap::const_iterator propMapItr;
-
- // This map contains the legal combinations of object/action/properties found in an ACL file
- static void loadValidationMap(objectMapPtr& map) {
- if (!map.get()) return;
- map->clear();
- propSetPtr p0; // empty ptr, used for no properties
-
- // == Exchanges ==
-
- propSetPtr p1(new propSet);
- p1->insert(PROP_TYPE);
- p1->insert(PROP_ALTERNATE);
- p1->insert(PROP_PASSIVE);
- p1->insert(PROP_DURABLE);
-
- propSetPtr p2(new propSet);
- p2->insert(PROP_ROUTINGKEY);
-
- propSetPtr p3(new propSet);
- p3->insert(PROP_QUEUENAME);
- p3->insert(PROP_ROUTINGKEY);
-
- actionMapPtr a0(new actionMap);
- a0->insert(actionPair(ACT_CREATE, p1));
- a0->insert(actionPair(ACT_DELETE, p0));
- a0->insert(actionPair(ACT_ACCESS, p0));
- a0->insert(actionPair(ACT_BIND, p2));
- a0->insert(actionPair(ACT_UNBIND, p2));
- a0->insert(actionPair(ACT_ACCESS, p3));
- a0->insert(actionPair(ACT_PUBLISH, p0));
-
- map->insert(objectPair(OBJ_EXCHANGE, a0));
-
- // == Queues ==
-
- propSetPtr p4(new propSet);
- p4->insert(PROP_ALTERNATE);
- p4->insert(PROP_PASSIVE);
- p4->insert(PROP_DURABLE);
- p4->insert(PROP_EXCLUSIVE);
- p4->insert(PROP_AUTODELETE);
- p4->insert(PROP_POLICYTYPE);
- p4->insert(PROP_MAXQUEUESIZE);
- p4->insert(PROP_MAXQUEUECOUNT);
-
- actionMapPtr a1(new actionMap);
- a1->insert(actionPair(ACT_ACCESS, p0));
- a1->insert(actionPair(ACT_CREATE, p4));
- a1->insert(actionPair(ACT_PURGE, p0));
- a1->insert(actionPair(ACT_DELETE, p0));
- a1->insert(actionPair(ACT_CONSUME, p0));
-
- map->insert(objectPair(OBJ_QUEUE, a1));
-
- // == Links ==
-
- actionMapPtr a2(new actionMap);
- a2->insert(actionPair(ACT_CREATE, p0));
-
- map->insert(objectPair(OBJ_LINK, a2));
-
- // == Method ==
-
- propSetPtr p5(new propSet);
- p5->insert(PROP_SCHEMAPACKAGE);
- p5->insert(PROP_SCHEMACLASS);
-
- actionMapPtr a4(new actionMap);
- a4->insert(actionPair(ACT_ACCESS, p5));
-
- map->insert(objectPair(OBJ_METHOD, a4));
- }
-
- static std::string propertyMapToString(const std::map<Property, std::string>* params) {
- std::ostringstream ss;
- ss << "{";
- if (params)
- {
- for (propMapItr pMItr = params->begin(); pMItr != params->end(); pMItr++) {
- ss << " " << getPropertyStr((Property) pMItr-> first) << "=" << pMItr->second;
- }
- }
- ss << " }";
- return ss.str();
- }
-};
-
-
-}} // namespace qpid::acl
-
-#endif // QPID_ACLMODULE_ACL_H
diff --git a/cpp/src/qpid/broker/AsyncCompletion.h b/cpp/src/qpid/broker/AsyncCompletion.h
deleted file mode 100644
index fef994438f..0000000000
--- a/cpp/src/qpid/broker/AsyncCompletion.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef _AsyncCompletion_
-#define _AsyncCompletion_
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/intrusive_ptr.hpp>
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/sys/AtomicValue.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Monitor.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Class to implement asynchronous notification of completion.
- *
- * Use-case: An "initiator" needs to wait for a set of "completers" to
- * finish a unit of work before an action can occur. This object
- * tracks the progress of the set of completers, and allows the action
- * to occur once all completers have signalled that they are done.
- *
- * The initiator and completers may be running in separate threads.
- *
- * The initiating thread is the thread that initiates the action,
- * i.e. the connection read thread.
- *
- * A completing thread is any thread that contributes to completion,
- * e.g. a store thread that does an async write.
- * There may be zero or more completers.
- *
- * When the work is complete, a callback is invoked. The callback
- * may be invoked in the Initiator thread, or one of the Completer
- * threads. The callback is passed a flag indicating whether or not
- * the callback is running under the context of the Initiator thread.
- *
- * Use model:
- * 1) Initiator thread invokes begin()
- * 2) After begin() has been invoked, zero or more Completers invoke
- * startCompleter(). Completers may be running in the same or
- * different thread as the Initiator, as long as they guarantee that
- * startCompleter() is invoked at least once before the Initiator invokes end().
- * 3) Completers may invoke finishCompleter() at any time, even after the
- * initiator has invoked end(). finishCompleter() may be called from any
- * thread.
- * 4) startCompleter()/finishCompleter() calls "nest": for each call to
- * startCompleter(), a corresponding call to finishCompleter() must be made.
- * Once the last finishCompleter() is called, the Completer must no longer
- * reference the completion object.
- * 5) The Initiator invokes end() at the point where it has finished
- * dispatching work to the Completers, and is prepared for the callback
- * handler to be invoked. Note: if there are no outstanding Completers
- * pending when the Initiator invokes end(), the callback will be invoked
- * directly, and the sync parameter will be set true. This indicates to the
- * Initiator that the callback is executing in the context of the end() call,
- * and the Initiator is free to optimize the handling of the completion,
- * assuming no need for synchronization with Completer threads.
- */
-
-class AsyncCompletion
-{
- public:
-
- /** Supplied by the Initiator to the end() method, allows for a callback
- * when all outstanding completers are done. If the callback cannot be
- * made during the end() call, the clone() method must supply a copy of
- * this callback object that persists after end() returns. The cloned
- * callback object will be used by the last completer thread, and
- * released when the callback returns.
- */
- class Callback : public RefCounted
- {
- public:
- virtual void completed(bool) = 0;
- virtual boost::intrusive_ptr<Callback> clone() = 0;
- };
-
- private:
- mutable qpid::sys::AtomicValue<uint32_t> completionsNeeded;
- mutable qpid::sys::Monitor callbackLock;
- bool inCallback, active;
-
- void invokeCallback(bool sync) {
- qpid::sys::Mutex::ScopedLock l(callbackLock);
- if (active) {
- if (callback.get()) {
- inCallback = true;
- {
- qpid::sys::Mutex::ScopedUnlock ul(callbackLock);
- callback->completed(sync);
- }
- inCallback = false;
- callback = boost::intrusive_ptr<Callback>();
- callbackLock.notifyAll();
- }
- active = false;
- }
- }
-
- protected:
- /** Invoked when all completers have signalled that they have completed
- * (via calls to finishCompleter()). bool == true if called via end()
- */
- boost::intrusive_ptr<Callback> callback;
-
- public:
- AsyncCompletion() : completionsNeeded(0), inCallback(false), active(true) {};
- virtual ~AsyncCompletion() { cancel(); }
-
-
- /** True when all outstanding operations have compeleted
- */
- bool isDone()
- {
- return !active;
- }
-
- /** Called to signal the start of an asynchronous operation. The operation
- * is considered pending until finishCompleter() is called.
- * E.g. called when initiating an async store operation.
- */
- void startCompleter() { ++completionsNeeded; }
-
- /** Called by completer to signal that it has finished the operation started
- * when startCompleter() was invoked.
- * e.g. called when async write complete.
- */
- void finishCompleter()
- {
- if (--completionsNeeded == 0) {
- invokeCallback(false);
- }
- }
-
- /** called by initiator before any calls to startCompleter can be done.
- */
- void begin()
- {
- ++completionsNeeded;
- }
-
- /** called by initiator after all potential completers have called
- * startCompleter().
- */
- void end(Callback& cb)
- {
- assert(completionsNeeded.get() > 0); // ensure begin() has been called!
- // the following only "decrements" the count if it is 1. This means
- // there are no more outstanding completers and we are done.
- if (completionsNeeded.boolCompareAndSwap(1, 0)) {
- // done! Complete immediately
- cb.completed(true);
- return;
- }
-
- // the compare-and-swap did not succeed. This means there are
- // outstanding completers pending (count > 1). Get a persistent
- // Callback object to use when the last completer is done.
- // Decrement after setting up the callback ensures that pending
- // completers cannot touch the callback until it is ready.
- callback = cb.clone();
- if (--completionsNeeded == 0) {
- // note that a completer may have completed during the
- // callback setup or decrement:
- invokeCallback(true);
- }
- }
-
- /** may be called by Initiator to cancel the callback. Will wait for
- * callback to complete if in progress.
- */
- virtual void cancel() {
- qpid::sys::Mutex::ScopedLock l(callbackLock);
- while (inCallback) callbackLock.wait();
- callback = boost::intrusive_ptr<Callback>();
- active = false;
- }
-};
-
-}} // qpid::broker::
-#endif /*!_AsyncCompletion_*/
diff --git a/cpp/src/qpid/broker/Bridge.cpp b/cpp/src/qpid/broker/Bridge.cpp
deleted file mode 100644
index 7fbbf4e2c4..0000000000
--- a/cpp/src/qpid/broker/Bridge.cpp
+++ /dev/null
@@ -1,323 +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.
- *
- */
-#include "qpid/broker/Bridge.h"
-#include "qpid/broker/FedOps.h"
-#include "qpid/broker/ConnectionState.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/broker/Link.h"
-#include "qpid/broker/LinkRegistry.h"
-#include "qpid/broker/SessionState.h"
-
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/framing/Uuid.h"
-#include "qpid/log/Statement.h"
-#include <iostream>
-
-using qpid::framing::FieldTable;
-using qpid::framing::Uuid;
-using qpid::framing::Buffer;
-using qpid::management::ManagementAgent;
-using std::string;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace qpid {
-namespace broker {
-
-void Bridge::PushHandler::handle(framing::AMQFrame& frame)
-{
- conn->received(frame);
-}
-
-Bridge::Bridge(Link* _link, framing::ChannelId _id, CancellationListener l,
- const _qmf::ArgsLinkBridge& _args) :
- link(_link), id(_id), args(_args), mgmtObject(0),
- listener(l), name(Uuid(true).str()), queueName("bridge_queue_"), persistenceId(0)
-{
- std::stringstream title;
- title << id << "_" << link->getBroker()->getFederationTag();
- queueName += title.str();
- ManagementAgent* agent = link->getBroker()->getManagementAgent();
- if (agent != 0) {
- mgmtObject = new _qmf::Bridge
- (agent, this, link, id, args.i_durable, args.i_src, args.i_dest,
- args.i_key, args.i_srcIsQueue, args.i_srcIsLocal,
- args.i_tag, args.i_excludes, args.i_dynamic, args.i_sync);
- agent->addObject(mgmtObject);
- }
- QPID_LOG(debug, "Bridge created from " << args.i_src << " to " << args.i_dest);
-}
-
-Bridge::~Bridge()
-{
- mgmtObject->resourceDestroy();
-}
-
-void Bridge::create(Connection& c)
-{
- connState = &c;
- conn = &c;
- FieldTable options;
- if (args.i_sync) options.setInt("qpid.sync_frequency", args.i_sync);
- SessionHandler& sessionHandler = c.getChannel(id);
- if (args.i_srcIsLocal) {
- if (args.i_dynamic)
- throw Exception("Dynamic routing not supported for push routes");
- // Point the bridging commands at the local connection handler
- pushHandler.reset(new PushHandler(&c));
- channelHandler.reset(new framing::ChannelHandler(id, pushHandler.get()));
-
- session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler));
- peer.reset(new framing::AMQP_ServerProxy(*channelHandler));
-
- session->attach(name, false);
- session->commandPoint(0,0);
- } else {
- sessionHandler.attachAs(name);
- // Point the bridging commands at the remote peer broker
- peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out));
- }
-
- if (args.i_srcIsLocal) sessionHandler.getSession()->disableReceiverTracking();
- if (args.i_srcIsQueue) {
- peer->getMessage().subscribe(args.i_src, args.i_dest, args.i_sync ? 0 : 1, 0, false, "", 0, options);
- peer->getMessage().flow(args.i_dest, 0, 0xFFFFFFFF);
- peer->getMessage().flow(args.i_dest, 1, 0xFFFFFFFF);
- QPID_LOG(debug, "Activated route from queue " << args.i_src << " to " << args.i_dest);
- } else {
- FieldTable queueSettings;
-
- if (args.i_tag.size()) {
- queueSettings.setString("qpid.trace.id", args.i_tag);
- } else {
- const string& peerTag = c.getFederationPeerTag();
- if (peerTag.size())
- queueSettings.setString("qpid.trace.id", peerTag);
- }
-
- if (args.i_excludes.size()) {
- queueSettings.setString("qpid.trace.exclude", args.i_excludes);
- } else {
- const string& localTag = link->getBroker()->getFederationTag();
- if (localTag.size())
- queueSettings.setString("qpid.trace.exclude", localTag);
- }
-
- bool durable = false;//should this be an arg, or would we use srcIsQueue for durable queues?
- bool autoDelete = !durable;//auto delete transient queues?
- peer->getQueue().declare(queueName, "", false, durable, true, autoDelete, queueSettings);
- if (!args.i_dynamic)
- peer->getExchange().bind(queueName, args.i_src, args.i_key, FieldTable());
- peer->getMessage().subscribe(queueName, args.i_dest, 1, 0, false, "", 0, FieldTable());
- peer->getMessage().flow(args.i_dest, 0, 0xFFFFFFFF);
- peer->getMessage().flow(args.i_dest, 1, 0xFFFFFFFF);
-
- if (args.i_dynamic) {
- Exchange::shared_ptr exchange = link->getBroker()->getExchanges().get(args.i_src);
- if (exchange.get() == 0)
- throw Exception("Exchange not found for dynamic route");
- exchange->registerDynamicBridge(this);
- QPID_LOG(debug, "Activated dynamic route for exchange " << args.i_src);
- } else {
- QPID_LOG(debug, "Activated static route from exchange " << args.i_src << " to " << args.i_dest);
- }
- }
- if (args.i_srcIsLocal) sessionHandler.getSession()->enableReceiverTracking();
-}
-
-void Bridge::cancel(Connection&)
-{
- if (resetProxy()) {
- peer->getMessage().cancel(args.i_dest);
- peer->getSession().detach(name);
- }
-}
-
-void Bridge::closed()
-{
- if (args.i_dynamic) {
- Exchange::shared_ptr exchange = link->getBroker()->getExchanges().get(args.i_src);
- if (exchange.get() != 0)
- exchange->removeDynamicBridge(this);
- }
-}
-
-void Bridge::destroy()
-{
- listener(this);
-}
-
-void Bridge::setPersistenceId(uint64_t pId) const
-{
- persistenceId = pId;
-}
-
-const string& Bridge::getName() const
-{
- return name;
-}
-
-Bridge::shared_ptr Bridge::decode(LinkRegistry& links, Buffer& buffer)
-{
- string host;
- uint16_t port;
- string src;
- string dest;
- string key;
- string id;
- string excludes;
-
- buffer.getShortString(host);
- port = buffer.getShort();
- bool durable(buffer.getOctet());
- buffer.getShortString(src);
- buffer.getShortString(dest);
- buffer.getShortString(key);
- bool is_queue(buffer.getOctet());
- bool is_local(buffer.getOctet());
- buffer.getShortString(id);
- buffer.getShortString(excludes);
- bool dynamic(buffer.getOctet());
- uint16_t sync = buffer.getShort();
-
- return links.declare(host, port, durable, src, dest, key,
- is_queue, is_local, id, excludes, dynamic, sync).first;
-}
-
-void Bridge::encode(Buffer& buffer) const
-{
- buffer.putShortString(string("bridge"));
- buffer.putShortString(link->getHost());
- buffer.putShort(link->getPort());
- buffer.putOctet(args.i_durable ? 1 : 0);
- buffer.putShortString(args.i_src);
- buffer.putShortString(args.i_dest);
- buffer.putShortString(args.i_key);
- buffer.putOctet(args.i_srcIsQueue ? 1 : 0);
- buffer.putOctet(args.i_srcIsLocal ? 1 : 0);
- buffer.putShortString(args.i_tag);
- buffer.putShortString(args.i_excludes);
- buffer.putOctet(args.i_dynamic ? 1 : 0);
- buffer.putShort(args.i_sync);
-}
-
-uint32_t Bridge::encodedSize() const
-{
- return link->getHost().size() + 1 // short-string (host)
- + 7 // short-string ("bridge")
- + 2 // port
- + 1 // durable
- + args.i_src.size() + 1
- + args.i_dest.size() + 1
- + args.i_key.size() + 1
- + 1 // srcIsQueue
- + 1 // srcIsLocal
- + args.i_tag.size() + 1
- + args.i_excludes.size() + 1
- + 1 // dynamic
- + 2; // sync
-}
-
-management::ManagementObject* Bridge::GetManagementObject (void) const
-{
- return (management::ManagementObject*) mgmtObject;
-}
-
-management::Manageable::status_t Bridge::ManagementMethod(uint32_t methodId,
- management::Args& /*args*/,
- string&)
-{
- if (methodId == _qmf::Bridge::METHOD_CLOSE) {
- //notify that we are closed
- destroy();
- return management::Manageable::STATUS_OK;
- } else {
- return management::Manageable::STATUS_UNKNOWN_METHOD;
- }
-}
-
-void Bridge::propagateBinding(const string& key, const string& tagList,
- const string& op, const string& origin,
- qpid::framing::FieldTable* extra_args)
-{
- const string& localTag = link->getBroker()->getFederationTag();
- const string& peerTag = connState->getFederationPeerTag();
-
- if (tagList.find(peerTag) == tagList.npos) {
- FieldTable bindArgs;
- if (extra_args) {
- for (qpid::framing::FieldTable::ValueMap::iterator i=extra_args->begin(); i != extra_args->end(); ++i) {
- bindArgs.insert((*i));
- }
- }
- string newTagList(tagList + string(tagList.empty() ? "" : ",") + localTag);
-
- bindArgs.setString(qpidFedOp, op);
- bindArgs.setString(qpidFedTags, newTagList);
- if (origin.empty())
- bindArgs.setString(qpidFedOrigin, localTag);
- else
- bindArgs.setString(qpidFedOrigin, origin);
-
- conn->requestIOProcessing(boost::bind(&Bridge::ioThreadPropagateBinding, this,
- queueName, args.i_src, key, bindArgs));
- }
-}
-
-void Bridge::sendReorigin()
-{
- FieldTable bindArgs;
-
- bindArgs.setString(qpidFedOp, fedOpReorigin);
- bindArgs.setString(qpidFedTags, link->getBroker()->getFederationTag());
-
- conn->requestIOProcessing(boost::bind(&Bridge::ioThreadPropagateBinding, this,
- queueName, args.i_src, args.i_key, bindArgs));
-}
-bool Bridge::resetProxy()
-{
- SessionHandler& sessionHandler = conn->getChannel(id);
- if (!sessionHandler.getSession()) peer.reset();
- else peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out));
- return peer.get();
-}
-
-void Bridge::ioThreadPropagateBinding(const string& queue, const string& exchange, const string& key, FieldTable args)
-{
- if (resetProxy()) {
- peer->getExchange().bind(queue, exchange, key, args);
- } else {
- QPID_LOG(error, "Cannot propagate binding for dynamic bridge as session has been detached, deleting dynamic bridge");
- destroy();
- }
-}
-
-bool Bridge::containsLocalTag(const string& tagList) const
-{
- const string& localTag = link->getBroker()->getFederationTag();
- return (tagList.find(localTag) != tagList.npos);
-}
-
-const string& Bridge::getLocalTag() const
-{
- return link->getBroker()->getFederationTag();
-}
-
-}}
diff --git a/cpp/src/qpid/broker/Bridge.h b/cpp/src/qpid/broker/Bridge.h
deleted file mode 100644
index a846254c57..0000000000
--- a/cpp/src/qpid/broker/Bridge.h
+++ /dev/null
@@ -1,111 +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.
- *
- */
-#ifndef _Bridge_
-#define _Bridge_
-
-#include "qpid/broker/PersistableConfig.h"
-#include "qpid/framing/AMQP_ServerProxy.h"
-#include "qpid/framing/ChannelHandler.h"
-#include "qpid/framing/Buffer.h"
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/management/Manageable.h"
-#include "qpid/broker/Exchange.h"
-#include "qmf/org/apache/qpid/broker/ArgsLinkBridge.h"
-#include "qmf/org/apache/qpid/broker/Bridge.h"
-
-#include <boost/function.hpp>
-#include <memory>
-
-namespace qpid {
-namespace broker {
-
-class Connection;
-class ConnectionState;
-class Link;
-class LinkRegistry;
-
-class Bridge : public PersistableConfig, public management::Manageable, public Exchange::DynamicBridge
-{
-public:
- typedef boost::shared_ptr<Bridge> shared_ptr;
- typedef boost::function<void(Bridge*)> CancellationListener;
-
- Bridge(Link* link, framing::ChannelId id, CancellationListener l,
- const qmf::org::apache::qpid::broker::ArgsLinkBridge& args);
- ~Bridge();
-
- void create(Connection& c);
- void cancel(Connection& c);
- void closed();
- void destroy();
- bool isDurable() { return args.i_durable; }
-
- management::ManagementObject* GetManagementObject() const;
- management::Manageable::status_t ManagementMethod(uint32_t methodId,
- management::Args& args,
- std::string& text);
-
- // PersistableConfig:
- void setPersistenceId(uint64_t id) const;
- uint64_t getPersistenceId() const { return persistenceId; }
- uint32_t encodedSize() const;
- void encode(framing::Buffer& buffer) const;
- const std::string& getName() const;
- static Bridge::shared_ptr decode(LinkRegistry& links, framing::Buffer& buffer);
-
- // Exchange::DynamicBridge methods
- void propagateBinding(const std::string& key, const std::string& tagList, const std::string& op, const std::string& origin, qpid::framing::FieldTable* extra_args=0);
- void sendReorigin();
- void ioThreadPropagateBinding(const std::string& queue, const std::string& exchange, const std::string& key, framing::FieldTable args);
- bool containsLocalTag(const std::string& tagList) const;
- const std::string& getLocalTag() const;
-
-private:
- struct PushHandler : framing::FrameHandler {
- PushHandler(Connection* c) { conn = c; }
- void handle(framing::AMQFrame& frame);
- Connection* conn;
- };
-
- std::auto_ptr<PushHandler> pushHandler;
- std::auto_ptr<framing::ChannelHandler> channelHandler;
- std::auto_ptr<framing::AMQP_ServerProxy::Session> session;
- std::auto_ptr<framing::AMQP_ServerProxy> peer;
-
- Link* link;
- framing::ChannelId id;
- qmf::org::apache::qpid::broker::ArgsLinkBridge args;
- qmf::org::apache::qpid::broker::Bridge* mgmtObject;
- CancellationListener listener;
- std::string name;
- std::string queueName;
- mutable uint64_t persistenceId;
- ConnectionState* connState;
- Connection* conn;
-
- bool resetProxy();
-};
-
-
-}}
-
-#endif
diff --git a/cpp/src/qpid/broker/Broker.cpp b/cpp/src/qpid/broker/Broker.cpp
deleted file mode 100644
index 240766c443..0000000000
--- a/cpp/src/qpid/broker/Broker.cpp
+++ /dev/null
@@ -1,967 +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.
- *
- */
-
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/ConnectionState.h"
-#include "qpid/broker/DirectExchange.h"
-#include "qpid/broker/FanOutExchange.h"
-#include "qpid/broker/HeadersExchange.h"
-#include "qpid/broker/MessageStoreModule.h"
-#include "qpid/broker/NullMessageStore.h"
-#include "qpid/broker/RecoveryManagerImpl.h"
-#include "qpid/broker/SaslAuthenticator.h"
-#include "qpid/broker/SecureConnectionFactory.h"
-#include "qpid/broker/TopicExchange.h"
-#include "qpid/broker/Link.h"
-#include "qpid/broker/ExpiryPolicy.h"
-#include "qpid/broker/QueueFlowLimit.h"
-
-#include "qmf/org/apache/qpid/broker/Package.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerCreate.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerDelete.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerEcho.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerGetLogLevel.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerQueueMoveMessages.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerSetLogLevel.h"
-#include "qmf/org/apache/qpid/broker/EventExchangeDeclare.h"
-#include "qmf/org/apache/qpid/broker/EventExchangeDelete.h"
-#include "qmf/org/apache/qpid/broker/EventQueueDeclare.h"
-#include "qmf/org/apache/qpid/broker/EventQueueDelete.h"
-#include "qmf/org/apache/qpid/broker/EventBind.h"
-#include "qmf/org/apache/qpid/broker/EventUnbind.h"
-#include "qpid/amqp_0_10/Codecs.h"
-#include "qpid/management/ManagementDirectExchange.h"
-#include "qpid/management/ManagementTopicExchange.h"
-#include "qpid/log/Logger.h"
-#include "qpid/log/Options.h"
-#include "qpid/log/Statement.h"
-#include "qpid/log/posix/SinkOptions.h"
-#include "qpid/framing/AMQFrame.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/framing/ProtocolInitiation.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/framing/Uuid.h"
-#include "qpid/sys/ProtocolFactory.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/sys/Dispatcher.h"
-#include "qpid/sys/Thread.h"
-#include "qpid/sys/Time.h"
-#include "qpid/sys/ConnectionInputHandler.h"
-#include "qpid/sys/ConnectionInputHandlerFactory.h"
-#include "qpid/sys/TimeoutHandler.h"
-#include "qpid/sys/SystemInfo.h"
-#include "qpid/Address.h"
-#include "qpid/StringUtils.h"
-#include "qpid/Url.h"
-#include "qpid/Version.h"
-
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-
-#include <iostream>
-#include <memory>
-
-using qpid::sys::ProtocolFactory;
-using qpid::sys::Poller;
-using qpid::sys::Dispatcher;
-using qpid::sys::Thread;
-using qpid::framing::FrameHandler;
-using qpid::framing::ChannelId;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::management::getManagementExecutionContext;
-using qpid::types::Variant;
-using std::string;
-using std::make_pair;
-
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace qpid {
-namespace broker {
-
-Broker::Options::Options(const std::string& name) :
- qpid::Options(name),
- noDataDir(0),
- port(DEFAULT_PORT),
- workerThreads(5),
- maxConnections(500),
- connectionBacklog(10),
- enableMgmt(1),
- mgmtPubInterval(10),
- queueCleanInterval(60*10),//10 minutes
- auth(SaslAuthenticator::available()),
- realm("QPID"),
- replayFlushLimit(0),
- replayHardLimit(0),
- queueLimit(100*1048576/*100M default limit*/),
- tcpNoDelay(false),
- requireEncrypted(false),
- maxSessionRate(0),
- asyncQueueEvents(false), // Must be false in a cluster.
- qmf2Support(true),
- qmf1Support(true),
- queueFlowStopRatio(80),
- queueFlowResumeRatio(70),
- queueThresholdEventRatio(80)
-{
- int c = sys::SystemInfo::concurrency();
- workerThreads=c+1;
- std::string home = getHome();
-
- if (home.length() == 0)
- dataDir += DEFAULT_DATA_DIR_LOCATION;
- else
- dataDir += home;
- dataDir += DEFAULT_DATA_DIR_NAME;
-
- addOptions()
- ("data-dir", optValue(dataDir,"DIR"), "Directory to contain persistent data generated by the broker")
- ("no-data-dir", optValue(noDataDir), "Don't use a data directory. No persistent configuration will be loaded or stored")
- ("port,p", optValue(port,"PORT"), "Tells the broker to listen on PORT")
- ("worker-threads", optValue(workerThreads, "N"), "Sets the broker thread pool size")
- ("max-connections", optValue(maxConnections, "N"), "Sets the maximum allowed connections")
- ("connection-backlog", optValue(connectionBacklog, "N"), "Sets the connection backlog limit for the server socket")
- ("mgmt-enable,m", optValue(enableMgmt,"yes|no"), "Enable Management")
- ("mgmt-qmf2", optValue(qmf2Support,"yes|no"), "Enable broadcast of management information over QMF v2")
- ("mgmt-qmf1", optValue(qmf1Support,"yes|no"), "Enable broadcast of management information over QMF v1")
- ("mgmt-pub-interval", optValue(mgmtPubInterval, "SECONDS"), "Management Publish Interval")
- ("queue-purge-interval", optValue(queueCleanInterval, "SECONDS"),
- "Interval between attempts to purge any expired messages from queues")
- ("auth", optValue(auth, "yes|no"), "Enable authentication, if disabled all incoming connections will be trusted")
- ("realm", optValue(realm, "REALM"), "Use the given realm when performing authentication")
- ("default-queue-limit", optValue(queueLimit, "BYTES"), "Default maximum size for queues (in bytes)")
- ("tcp-nodelay", optValue(tcpNoDelay), "Set TCP_NODELAY on TCP connections")
- ("require-encryption", optValue(requireEncrypted), "Only accept connections that are encrypted")
- ("known-hosts-url", optValue(knownHosts, "URL or 'none'"), "URL to send as 'known-hosts' to clients ('none' implies empty list)")
- ("sasl-config", optValue(saslConfigPath, "DIR"), "gets sasl config info from nonstandard location")
- ("max-session-rate", optValue(maxSessionRate, "MESSAGES/S"), "Sets the maximum message rate per session (0=unlimited)")
- ("async-queue-events", optValue(asyncQueueEvents, "yes|no"), "Set Queue Events async, used for services like replication")
- ("default-flow-stop-threshold", optValue(queueFlowStopRatio, "PERCENT"), "Percent of queue's maximum capacity at which flow control is activated.")
- ("default-flow-resume-threshold", optValue(queueFlowResumeRatio, "PERCENT"), "Percent of queue's maximum capacity at which flow control is de-activated.")
- ("default-event-threshold-ratio", optValue(queueThresholdEventRatio, "%age of limit"), "The ratio of any specified queue limit at which an event will be raised");
-}
-
-const std::string empty;
-const std::string amq_direct("amq.direct");
-const std::string amq_topic("amq.topic");
-const std::string amq_fanout("amq.fanout");
-const std::string amq_match("amq.match");
-const std::string qpid_management("qpid.management");
-const std::string knownHostsNone("none");
-
-Broker::Broker(const Broker::Options& conf) :
- poller(new Poller),
- config(conf),
- managementAgent(conf.enableMgmt ? new ManagementAgent(conf.qmf1Support,
- conf.qmf2Support)
- : 0),
- store(new NullMessageStore),
- acl(0),
- dataDir(conf.noDataDir ? std::string() : conf.dataDir),
- queues(this),
- exchanges(this),
- links(this),
- factory(new SecureConnectionFactory(*this)),
- dtxManager(timer),
- sessionManager(
- qpid::SessionState::Configuration(
- conf.replayFlushLimit*1024, // convert kb to bytes.
- conf.replayHardLimit*1024),
- *this),
- queueCleaner(queues, timer),
- queueEvents(poller,!conf.asyncQueueEvents),
- recovery(true),
- inCluster(false),
- clusterUpdatee(false),
- expiryPolicy(new ExpiryPolicy),
- connectionCounter(conf.maxConnections),
- getKnownBrokers(boost::bind(&Broker::getKnownBrokersImpl, this)),
- deferDelivery(boost::bind(&Broker::deferDeliveryImpl, this, _1, _2))
-{
- try {
- if (conf.enableMgmt) {
- QPID_LOG(info, "Management enabled");
- managementAgent->configure(dataDir.isEnabled() ? dataDir.getPath() : string(),
- conf.mgmtPubInterval, this, conf.workerThreads + 3);
- managementAgent->setName("apache.org", "qpidd");
- _qmf::Package packageInitializer(managementAgent.get());
-
- System* system = new System (dataDir.isEnabled() ? dataDir.getPath() : string(), this);
- systemObject = System::shared_ptr(system);
-
- mgmtObject = new _qmf::Broker(managementAgent.get(), this, system, "amqp-broker");
- mgmtObject->set_systemRef(system->GetManagementObject()->getObjectId());
- mgmtObject->set_port(conf.port);
- mgmtObject->set_workerThreads(conf.workerThreads);
- mgmtObject->set_maxConns(conf.maxConnections);
- mgmtObject->set_connBacklog(conf.connectionBacklog);
- mgmtObject->set_mgmtPubInterval(conf.mgmtPubInterval);
- mgmtObject->set_version(qpid::version);
- if (dataDir.isEnabled())
- mgmtObject->set_dataDir(dataDir.getPath());
- else
- mgmtObject->clr_dataDir();
-
- managementAgent->addObject(mgmtObject, 0, true);
-
- // Since there is currently no support for virtual hosts, a placeholder object
- // representing the implied single virtual host is added here to keep the
- // management schema correct.
- Vhost* vhost = new Vhost(this, this);
- vhostObject = Vhost::shared_ptr(vhost);
- framing::Uuid uuid(managementAgent->getUuid());
- federationTag = uuid.str();
- vhostObject->setFederationTag(federationTag);
-
- queues.setParent(vhost);
- exchanges.setParent(vhost);
- links.setParent(vhost);
- } else {
- // Management is disabled so there is no broker management ID.
- // Create a unique uuid to use as the federation tag.
- framing::Uuid uuid(true);
- federationTag = uuid.str();
- }
-
- QueuePolicy::setDefaultMaxSize(conf.queueLimit);
-
- // Early-Initialize plugins
- Plugin::earlyInitAll(*this);
-
- QueueFlowLimit::setDefaults(conf.queueLimit, conf.queueFlowStopRatio, conf.queueFlowResumeRatio);
-
- // If no plugin store module registered itself, set up the null store.
- if (NullMessageStore::isNullStore(store.get()))
- setStore();
-
- exchanges.declare(empty, DirectExchange::typeName); // Default exchange.
-
- if (store.get() != 0) {
- // The cluster plug-in will setRecovery(false) on all but the first
- // broker to join a cluster.
- if (getRecovery()) {
- RecoveryManagerImpl recoverer(queues, exchanges, links, dtxManager);
- store->recover(recoverer);
- }
- else {
- QPID_LOG(notice, "Cluster recovery: recovered journal data discarded and journal files pushed down");
- store->truncateInit(true); // save old files in subdir
- }
- }
-
- //ensure standard exchanges exist (done after recovery from store)
- declareStandardExchange(amq_direct, DirectExchange::typeName);
- declareStandardExchange(amq_topic, TopicExchange::typeName);
- declareStandardExchange(amq_fanout, FanOutExchange::typeName);
- declareStandardExchange(amq_match, HeadersExchange::typeName);
-
- if(conf.enableMgmt) {
- exchanges.declare(qpid_management, ManagementTopicExchange::typeName);
- Exchange::shared_ptr mExchange = exchanges.get(qpid_management);
- Exchange::shared_ptr dExchange = exchanges.get(amq_direct);
- managementAgent->setExchange(mExchange, dExchange);
- boost::dynamic_pointer_cast<ManagementTopicExchange>(mExchange)->setManagmentAgent(managementAgent.get(), 1);
-
- std::string qmfTopic("qmf.default.topic");
- std::string qmfDirect("qmf.default.direct");
-
- std::pair<Exchange::shared_ptr, bool> topicPair(exchanges.declare(qmfTopic, ManagementTopicExchange::typeName));
- std::pair<Exchange::shared_ptr, bool> directPair(exchanges.declare(qmfDirect, ManagementDirectExchange::typeName));
-
- boost::dynamic_pointer_cast<ManagementDirectExchange>(directPair.first)->setManagmentAgent(managementAgent.get(), 2);
- boost::dynamic_pointer_cast<ManagementTopicExchange>(topicPair.first)->setManagmentAgent(managementAgent.get(), 2);
-
- managementAgent->setExchangeV2(topicPair.first, directPair.first);
- }
- else
- QPID_LOG(info, "Management not enabled");
-
- /**
- * SASL setup, can fail and terminate startup
- */
- if (conf.auth) {
- SaslAuthenticator::init(qpid::saslName, conf.saslConfigPath);
- QPID_LOG(info, "SASL enabled");
- } else {
- QPID_LOG(notice, "SASL disabled: No Authentication Performed");
- }
-
- // Initialize plugins
- Plugin::initializeAll(*this);
-
- if (managementAgent.get()) managementAgent->pluginsInitialized();
-
- if (conf.queueCleanInterval) {
- queueCleaner.start(conf.queueCleanInterval * qpid::sys::TIME_SEC);
- }
-
- //initialize known broker urls (TODO: add support for urls for other transports (SSL, RDMA)):
- if (conf.knownHosts.empty()) {
- boost::shared_ptr<ProtocolFactory> factory = getProtocolFactory(TCP_TRANSPORT);
- if (factory) {
- knownBrokers.push_back ( qpid::Url::getIpAddressesUrl ( factory->getPort() ) );
- }
- } else if (conf.knownHosts != knownHostsNone) {
- knownBrokers.push_back(Url(conf.knownHosts));
- }
- } catch (const std::exception& /*e*/) {
- finalize();
- throw;
- }
-}
-
-void Broker::declareStandardExchange(const std::string& name, const std::string& type)
-{
- bool storeEnabled = store.get() != NULL;
- std::pair<Exchange::shared_ptr, bool> status = exchanges.declare(name, type, storeEnabled);
- if (status.second && storeEnabled) {
- store->create(*status.first, framing::FieldTable ());
- }
-}
-
-
-boost::intrusive_ptr<Broker> Broker::create(int16_t port)
-{
- Options config;
- config.port=port;
- return create(config);
-}
-
-boost::intrusive_ptr<Broker> Broker::create(const Options& opts)
-{
- return boost::intrusive_ptr<Broker>(new Broker(opts));
-}
-
-void Broker::setStore (boost::shared_ptr<MessageStore>& _store)
-{
- store.reset(new MessageStoreModule (_store));
- setStore();
-}
-
-void Broker::setStore () {
- queues.setStore (store.get());
- dtxManager.setStore (store.get());
- links.setStore (store.get());
-}
-
-void Broker::run() {
- if (config.workerThreads > 0) {
- QPID_LOG(notice, "Broker running");
- Dispatcher d(poller);
- int numIOThreads = config.workerThreads;
- std::vector<Thread> t(numIOThreads-1);
-
- // Run n-1 io threads
- for (int i=0; i<numIOThreads-1; ++i)
- t[i] = Thread(d);
-
- // Run final thread
- d.run();
-
- // Now wait for n-1 io threads to exit
- for (int i=0; i<numIOThreads-1; ++i) {
- t[i].join();
- }
- } else {
- throw Exception((boost::format("Invalid value for worker-threads: %1%") % config.workerThreads).str());
- }
-}
-
-void Broker::shutdown() {
- // NB: this function must be async-signal safe, it must not
- // call any function that is not async-signal safe.
- // Any unsafe shutdown actions should be done in the destructor.
- poller->shutdown();
-}
-
-Broker::~Broker() {
- shutdown();
- queueEvents.shutdown();
- finalize(); // Finalize any plugins.
- if (config.auth)
- SaslAuthenticator::fini();
- timer.stop();
- QPID_LOG(notice, "Shut down");
-}
-
-ManagementObject* Broker::GetManagementObject(void) const
-{
- return (ManagementObject*) mgmtObject;
-}
-
-Manageable* Broker::GetVhostObject(void) const
-{
- return vhostObject.get();
-}
-
-Manageable::status_t Broker::ManagementMethod (uint32_t methodId,
- Args& args,
- string&)
-{
- Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD;
-
- switch (methodId)
- {
- case _qmf::Broker::METHOD_ECHO :
- QPID_LOG (debug, "Broker::echo("
- << dynamic_cast<_qmf::ArgsBrokerEcho&>(args).io_sequence
- << ", "
- << dynamic_cast<_qmf::ArgsBrokerEcho&>(args).io_body
- << ")");
- status = Manageable::STATUS_OK;
- break;
- case _qmf::Broker::METHOD_CONNECT : {
- _qmf::ArgsBrokerConnect& hp=
- dynamic_cast<_qmf::ArgsBrokerConnect&>(args);
-
- QPID_LOG (debug, "Broker::connect()");
- string transport = hp.i_transport.empty() ? TCP_TRANSPORT : hp.i_transport;
- if (!getProtocolFactory(transport)) {
- QPID_LOG(error, "Transport '" << transport << "' not supported");
- return Manageable::STATUS_NOT_IMPLEMENTED;
- }
- std::pair<Link::shared_ptr, bool> response =
- links.declare (hp.i_host, hp.i_port, transport, hp.i_durable,
- hp.i_authMechanism, hp.i_username, hp.i_password);
- if (hp.i_durable && response.second)
- store->create(*response.first);
- status = Manageable::STATUS_OK;
- break;
- }
- case _qmf::Broker::METHOD_QUEUEMOVEMESSAGES : {
- _qmf::ArgsBrokerQueueMoveMessages& moveArgs=
- dynamic_cast<_qmf::ArgsBrokerQueueMoveMessages&>(args);
- QPID_LOG (debug, "Broker::queueMoveMessages()");
- if (queueMoveMessages(moveArgs.i_srcQueue, moveArgs.i_destQueue, moveArgs.i_qty))
- status = Manageable::STATUS_OK;
- else
- return Manageable::STATUS_PARAMETER_INVALID;
- break;
- }
- case _qmf::Broker::METHOD_SETLOGLEVEL :
- setLogLevel(dynamic_cast<_qmf::ArgsBrokerSetLogLevel&>(args).i_level);
- QPID_LOG (debug, "Broker::setLogLevel()");
- status = Manageable::STATUS_OK;
- break;
- case _qmf::Broker::METHOD_GETLOGLEVEL :
- dynamic_cast<_qmf::ArgsBrokerGetLogLevel&>(args).o_level = getLogLevel();
- QPID_LOG (debug, "Broker::getLogLevel()");
- status = Manageable::STATUS_OK;
- break;
- case _qmf::Broker::METHOD_CREATE :
- {
- _qmf::ArgsBrokerCreate& a = dynamic_cast<_qmf::ArgsBrokerCreate&>(args);
- createObject(a.i_type, a.i_name, a.i_properties, a.i_strict, getManagementExecutionContext());
- status = Manageable::STATUS_OK;
- break;
- }
- case _qmf::Broker::METHOD_DELETE :
- {
- _qmf::ArgsBrokerDelete& a = dynamic_cast<_qmf::ArgsBrokerDelete&>(args);
- deleteObject(a.i_type, a.i_name, a.i_options, getManagementExecutionContext());
- status = Manageable::STATUS_OK;
- break;
- }
- default:
- QPID_LOG (debug, "Broker ManagementMethod not implemented: id=" << methodId << "]");
- status = Manageable::STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- return status;
-}
-
-namespace
-{
-const std::string TYPE_QUEUE("queue");
-const std::string TYPE_EXCHANGE("exchange");
-const std::string TYPE_TOPIC("topic");
-const std::string TYPE_BINDING("binding");
-const std::string DURABLE("durable");
-const std::string AUTO_DELETE("auto-delete");
-const std::string ALTERNATE_EXCHANGE("alternate-exchange");
-const std::string EXCHANGE_TYPE("exchange-type");
-const std::string QUEUE_NAME("queue");
-const std::string EXCHANGE_NAME("exchange");
-
-const std::string _TRUE("true");
-const std::string _FALSE("false");
-}
-
-struct InvalidBindingIdentifier : public qpid::Exception
-{
- InvalidBindingIdentifier(const std::string& name) : qpid::Exception(name) {}
- std::string getPrefix() const { return "invalid binding"; }
-};
-
-struct BindingIdentifier
-{
- std::string exchange;
- std::string queue;
- std::string key;
-
- BindingIdentifier(const std::string& name)
- {
- std::vector<std::string> path;
- split(path, name, "/");
- switch (path.size()) {
- case 1:
- queue = path[0];
- break;
- case 2:
- exchange = path[0];
- queue = path[1];
- break;
- case 3:
- exchange = path[0];
- queue = path[1];
- key = path[2];
- break;
- default:
- throw InvalidBindingIdentifier(name);
- }
- }
-};
-
-struct ObjectAlreadyExists : public qpid::Exception
-{
- ObjectAlreadyExists(const std::string& name) : qpid::Exception(name) {}
- std::string getPrefix() const { return "object already exists"; }
-};
-
-struct UnknownObjectType : public qpid::Exception
-{
- UnknownObjectType(const std::string& type) : qpid::Exception(type) {}
- std::string getPrefix() const { return "unknown object type"; }
-};
-
-void Broker::createObject(const std::string& type, const std::string& name,
- const Variant::Map& properties, bool /*strict*/, const ConnectionState* context)
-{
- std::string userId;
- std::string connectionId;
- if (context) {
- userId = context->getUserId();
- connectionId = context->getUrl();
- }
- //TODO: implement 'strict' option (check there are no unrecognised properties)
- QPID_LOG (debug, "Broker::create(" << type << ", " << name << "," << properties << ")");
- if (type == TYPE_QUEUE) {
- bool durable(false);
- bool autodelete(false);
- std::string alternateExchange;
- Variant::Map extensions;
- for (Variant::Map::const_iterator i = properties.begin(); i != properties.end(); ++i) {
- // extract durable, auto-delete and alternate-exchange properties
- if (i->first == DURABLE) durable = i->second;
- else if (i->first == AUTO_DELETE) autodelete = i->second;
- else if (i->first == ALTERNATE_EXCHANGE) alternateExchange = i->second.asString();
- //treat everything else as extension properties
- else extensions[i->first] = i->second;
- }
- framing::FieldTable arguments;
- amqp_0_10::translate(extensions, arguments);
-
- std::pair<boost::shared_ptr<Queue>, bool> result =
- createQueue(name, durable, autodelete, 0, alternateExchange, arguments, userId, connectionId);
- if (!result.second) {
- throw ObjectAlreadyExists(name);
- }
- } else if (type == TYPE_EXCHANGE || type == TYPE_TOPIC) {
- bool durable(false);
- std::string exchangeType("topic");
- std::string alternateExchange;
- Variant::Map extensions;
- for (Variant::Map::const_iterator i = properties.begin(); i != properties.end(); ++i) {
- // extract durable, auto-delete and alternate-exchange properties
- if (i->first == DURABLE) durable = i->second;
- else if (i->first == EXCHANGE_TYPE) exchangeType = i->second.asString();
- else if (i->first == ALTERNATE_EXCHANGE) alternateExchange = i->second.asString();
- //treat everything else as extension properties
- else extensions[i->first] = i->second;
- }
- framing::FieldTable arguments;
- amqp_0_10::translate(extensions, arguments);
-
- try {
- std::pair<boost::shared_ptr<Exchange>, bool> result =
- createExchange(name, exchangeType, durable, alternateExchange, arguments, userId, connectionId);
- if (!result.second) {
- throw ObjectAlreadyExists(name);
- }
- } catch (const UnknownExchangeTypeException&) {
- throw Exception(QPID_MSG("Invalid exchange type: " << exchangeType));
- }
- } else if (type == TYPE_BINDING) {
- BindingIdentifier binding(name);
- std::string exchangeType("topic");
- Variant::Map extensions;
- for (Variant::Map::const_iterator i = properties.begin(); i != properties.end(); ++i) {
- // extract durable, auto-delete and alternate-exchange properties
- if (i->first == EXCHANGE_TYPE) exchangeType = i->second.asString();
- //treat everything else as extension properties
- else extensions[i->first] = i->second;
- }
- framing::FieldTable arguments;
- amqp_0_10::translate(extensions, arguments);
-
- bind(binding.queue, binding.exchange, binding.key, arguments, userId, connectionId);
- } else {
- throw UnknownObjectType(type);
- }
-}
-
-void Broker::deleteObject(const std::string& type, const std::string& name,
- const Variant::Map& options, const ConnectionState* context)
-{
- std::string userId;
- std::string connectionId;
- if (context) {
- userId = context->getUserId();
- connectionId = context->getUrl();
- }
- QPID_LOG (debug, "Broker::delete(" << type << ", " << name << "," << options << ")");
- if (type == TYPE_QUEUE) {
- deleteQueue(name, userId, connectionId);
- } else if (type == TYPE_EXCHANGE || type == TYPE_TOPIC) {
- deleteExchange(name, userId, connectionId);
- } else if (type == TYPE_BINDING) {
- BindingIdentifier binding(name);
- unbind(binding.queue, binding.exchange, binding.key, userId, connectionId);
- } else {
- throw UnknownObjectType(type);
- }
-
-}
-
-void Broker::setLogLevel(const std::string& level)
-{
- QPID_LOG(notice, "Changing log level to " << level);
- std::vector<std::string> selectors;
- split(selectors, level, ", ");
- qpid::log::Logger::instance().reconfigure(selectors);
-}
-
-std::string Broker::getLogLevel()
-{
- std::string level;
- const std::vector<std::string>& selectors = qpid::log::Logger::instance().getOptions().selectors;
- for (std::vector<std::string>::const_iterator i = selectors.begin(); i != selectors.end(); ++i) {
- if (i != selectors.begin()) level += std::string(",");
- level += *i;
- }
- return level;
-}
-
-boost::shared_ptr<ProtocolFactory> Broker::getProtocolFactory(const std::string& name) const {
- ProtocolFactoryMap::const_iterator i
- = name.empty() ? protocolFactories.begin() : protocolFactories.find(name);
- if (i == protocolFactories.end()) return boost::shared_ptr<ProtocolFactory>();
- else return i->second;
-}
-
-uint16_t Broker::getPort(const std::string& name) const {
- boost::shared_ptr<ProtocolFactory> factory = getProtocolFactory(name);
- if (factory) {
- return factory->getPort();
- } else {
- throw NoSuchTransportException(QPID_MSG("No such transport: '" << name << "'"));
- }
-}
-
-void Broker::registerProtocolFactory(const std::string& name, ProtocolFactory::shared_ptr protocolFactory) {
- protocolFactories[name] = protocolFactory;
- Url::addProtocol(name);
-}
-
-void Broker::accept() {
- for (ProtocolFactoryMap::const_iterator i = protocolFactories.begin(); i != protocolFactories.end(); i++) {
- i->second->accept(poller, factory.get());
- }
-}
-
-void Broker::connect(
- const std::string& host, uint16_t port, const std::string& transport,
- boost::function2<void, int, std::string> failed,
- sys::ConnectionCodec::Factory* f)
-{
- boost::shared_ptr<ProtocolFactory> pf = getProtocolFactory(transport);
- if (pf) pf->connect(poller, host, port, f ? f : factory.get(), failed);
- else throw NoSuchTransportException(QPID_MSG("Unsupported transport type: " << transport));
-}
-
-void Broker::connect(
- const Url& url,
- boost::function2<void, int, std::string> failed,
- sys::ConnectionCodec::Factory* f)
-{
- url.throwIfEmpty();
- const Address& addr=url[0];
- connect(addr.host, addr.port, addr.protocol, failed, f);
-}
-
-uint32_t Broker::queueMoveMessages(
- const std::string& srcQueue,
- const std::string& destQueue,
- uint32_t qty)
-{
- Queue::shared_ptr src_queue = queues.find(srcQueue);
- if (!src_queue)
- return 0;
- Queue::shared_ptr dest_queue = queues.find(destQueue);
- if (!dest_queue)
- return 0;
-
- return src_queue->move(dest_queue, qty);
-}
-
-
-boost::shared_ptr<sys::Poller> Broker::getPoller() { return poller; }
-
-std::vector<Url>
-Broker::getKnownBrokersImpl()
-{
- return knownBrokers;
-}
-
-bool Broker::deferDeliveryImpl(const std::string& ,
- const boost::intrusive_ptr<Message>& )
-{ return false; }
-
-void Broker::setClusterTimer(std::auto_ptr<sys::Timer> t) {
- clusterTimer = t;
-}
-
-const std::string Broker::TCP_TRANSPORT("tcp");
-
-
-std::pair<boost::shared_ptr<Queue>, bool> Broker::createQueue(
- const std::string& name,
- bool durable,
- bool autodelete,
- const OwnershipToken* owner,
- const std::string& alternateExchange,
- const qpid::framing::FieldTable& arguments,
- const std::string& userId,
- const std::string& connectionId)
-{
- if (acl) {
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_ALTERNATE, alternateExchange));
- params.insert(make_pair(acl::PROP_PASSIVE, _FALSE));
- params.insert(make_pair(acl::PROP_DURABLE, durable ? _TRUE : _FALSE));
- params.insert(make_pair(acl::PROP_EXCLUSIVE, owner ? _TRUE : _FALSE));
- params.insert(make_pair(acl::PROP_AUTODELETE, autodelete ? _TRUE : _FALSE));
- params.insert(make_pair(acl::PROP_POLICYTYPE, arguments.getAsString("qpid.policy_type")));
- params.insert(make_pair(acl::PROP_MAXQUEUECOUNT, boost::lexical_cast<string>(arguments.getAsInt("qpid.max_count"))));
- params.insert(make_pair(acl::PROP_MAXQUEUESIZE, boost::lexical_cast<string>(arguments.getAsInt64("qpid.max_size"))));
-
- if (!acl->authorise(userId,acl::ACT_CREATE,acl::OBJ_QUEUE,name,&params) )
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
- }
-
- Exchange::shared_ptr alternate;
- if (!alternateExchange.empty()) {
- alternate = exchanges.get(alternateExchange);
- if (!alternate) throw framing::NotFoundException(QPID_MSG("Alternate exchange does not exist: " << alternateExchange));
- }
-
- std::pair<Queue::shared_ptr, bool> result = queues.declare(name, durable, autodelete, owner, alternate, arguments);
- if (result.second) {
- //add default binding:
- result.first->bind(exchanges.getDefault(), name);
-
- if (managementAgent.get()) {
- //TODO: debatable whether we should raise an event here for
- //create when this is a 'declare' event; ideally add a create
- //event instead?
- managementAgent->raiseEvent(
- _qmf::EventQueueDeclare(connectionId, userId, name,
- durable, owner, autodelete,
- ManagementAgent::toMap(arguments),
- "created"));
- }
- }
- return result;
-}
-
-void Broker::deleteQueue(const std::string& name, const std::string& userId,
- const std::string& connectionId, QueueFunctor check)
-{
- if (acl && !acl->authorise(userId,acl::ACT_DELETE,acl::OBJ_QUEUE,name,NULL)) {
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue delete request from " << userId));
- }
-
- Queue::shared_ptr queue = queues.find(name);
- if (queue) {
- if (check) check(queue);
- queues.destroy(name);
- queue->destroyed();
- } else {
- throw framing::NotFoundException(QPID_MSG("Delete failed. No such queue: " << name));
- }
-
- if (managementAgent.get())
- managementAgent->raiseEvent(_qmf::EventQueueDelete(connectionId, userId, name));
-
-}
-
-std::pair<Exchange::shared_ptr, bool> Broker::createExchange(
- const std::string& name,
- const std::string& type,
- bool durable,
- const std::string& alternateExchange,
- const qpid::framing::FieldTable& arguments,
- const std::string& userId,
- const std::string& connectionId)
-{
- if (acl) {
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_TYPE, type));
- params.insert(make_pair(acl::PROP_ALTERNATE, alternateExchange));
- params.insert(make_pair(acl::PROP_PASSIVE, _FALSE));
- params.insert(make_pair(acl::PROP_DURABLE, durable ? _TRUE : _FALSE));
- if (!acl->authorise(userId,acl::ACT_CREATE,acl::OBJ_EXCHANGE,name,&params) )
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange create request from " << userId));
- }
-
- Exchange::shared_ptr alternate;
- if (!alternateExchange.empty()) {
- alternate = exchanges.get(alternateExchange);
- if (!alternate) throw framing::NotFoundException(QPID_MSG("Alternate exchange does not exist: " << alternateExchange));
- }
-
- std::pair<Exchange::shared_ptr, bool> result;
- result = exchanges.declare(name, type, durable, arguments);
- if (result.second) {
- if (alternate) {
- result.first->setAlternate(alternate);
- alternate->incAlternateUsers();
- }
- if (durable) {
- store->create(*result.first, arguments);
- }
- if (managementAgent.get()) {
- //TODO: debatable whether we should raise an event here for
- //create when this is a 'declare' event; ideally add a create
- //event instead?
- managementAgent->raiseEvent(_qmf::EventExchangeDeclare(connectionId,
- userId,
- name,
- type,
- alternateExchange,
- durable,
- false,
- ManagementAgent::toMap(arguments),
- "created"));
- }
- }
- return result;
-}
-
-void Broker::deleteExchange(const std::string& name, const std::string& userId,
- const std::string& connectionId)
-{
- if (acl) {
- if (!acl->authorise(userId,acl::ACT_DELETE,acl::OBJ_EXCHANGE,name,NULL) )
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange delete request from " << userId));
- }
-
- Exchange::shared_ptr exchange(exchanges.get(name));
- if (!exchange) throw framing::NotFoundException(QPID_MSG("Delete failed. No such exchange: " << name));
- if (exchange->inUseAsAlternate()) throw framing::NotAllowedException(QPID_MSG("Exchange in use as alternate-exchange."));
- if (exchange->isDurable()) store->destroy(*exchange);
- if (exchange->getAlternate()) exchange->getAlternate()->decAlternateUsers();
- exchanges.destroy(name);
-
- if (managementAgent.get())
- managementAgent->raiseEvent(_qmf::EventExchangeDelete(connectionId, userId, name));
-
-}
-
-void Broker::bind(const std::string& queueName,
- const std::string& exchangeName,
- const std::string& key,
- const qpid::framing::FieldTable& arguments,
- const std::string& userId,
- const std::string& connectionId)
-{
- if (acl) {
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_QUEUENAME, queueName));
- params.insert(make_pair(acl::PROP_ROUTINGKEY, key));
-
- if (!acl->authorise(userId,acl::ACT_BIND,acl::OBJ_EXCHANGE,exchangeName,&params))
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange bind request from " << userId));
- }
-
- Queue::shared_ptr queue = queues.find(queueName);
- Exchange::shared_ptr exchange = exchanges.get(exchangeName);
- if (!queue) {
- throw framing::NotFoundException(QPID_MSG("Bind failed. No such queue: " << queueName));
- } else if (!exchange) {
- throw framing::NotFoundException(QPID_MSG("Bind failed. No such exchange: " << exchangeName));
- } else {
- if (queue->bind(exchange, key, arguments)) {
- if (managementAgent.get()) {
- managementAgent->raiseEvent(_qmf::EventBind(connectionId, userId, exchangeName,
- queueName, key, ManagementAgent::toMap(arguments)));
- }
- }
- }
-}
-
-void Broker::unbind(const std::string& queueName,
- const std::string& exchangeName,
- const std::string& key,
- const std::string& userId,
- const std::string& connectionId)
-{
- if (acl) {
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_QUEUENAME, queueName));
- params.insert(make_pair(acl::PROP_ROUTINGKEY, key));
- if (!acl->authorise(userId,acl::ACT_UNBIND,acl::OBJ_EXCHANGE,exchangeName,&params) )
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange unbind request from " << userId));
- }
-
- Queue::shared_ptr queue = queues.find(queueName);
- Exchange::shared_ptr exchange = exchanges.get(exchangeName);
- if (!queue) {
- throw framing::NotFoundException(QPID_MSG("Bind failed. No such queue: " << queueName));
- } else if (!exchange) {
- throw framing::NotFoundException(QPID_MSG("Bind failed. No such exchange: " << exchangeName));
- } else {
- if (exchange->unbind(queue, key, 0)) {
- if (exchange->isDurable() && queue->isDurable()) {
- store->unbind(*exchange, *queue, key, qpid::framing::FieldTable());
- }
- if (managementAgent.get()) {
- managementAgent->raiseEvent(_qmf::EventUnbind(connectionId, userId, exchangeName, queueName, key));
- }
- }
- }
-}
-
-}} // namespace qpid::broker
-
diff --git a/cpp/src/qpid/broker/Broker.h b/cpp/src/qpid/broker/Broker.h
deleted file mode 100644
index 6d585bf614..0000000000
--- a/cpp/src/qpid/broker/Broker.h
+++ /dev/null
@@ -1,351 +0,0 @@
-#ifndef _Broker_
-#define _Broker_
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/ConnectionFactory.h"
-#include "qpid/broker/ConnectionToken.h"
-#include "qpid/broker/DirectExchange.h"
-#include "qpid/broker/DtxManager.h"
-#include "qpid/broker/ExchangeRegistry.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/QueueRegistry.h"
-#include "qpid/broker/LinkRegistry.h"
-#include "qpid/broker/SessionManager.h"
-#include "qpid/broker/QueueCleaner.h"
-#include "qpid/broker/QueueEvents.h"
-#include "qpid/broker/Vhost.h"
-#include "qpid/broker/System.h"
-#include "qpid/broker/ExpiryPolicy.h"
-#include "qpid/management/Manageable.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qmf/org/apache/qpid/broker/Broker.h"
-#include "qmf/org/apache/qpid/broker/ArgsBrokerConnect.h"
-#include "qpid/Options.h"
-#include "qpid/Plugin.h"
-#include "qpid/DataDir.h"
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/OutputHandler.h"
-#include "qpid/framing/ProtocolInitiation.h"
-#include "qpid/sys/Runnable.h"
-#include "qpid/sys/Timer.h"
-#include "qpid/types/Variant.h"
-#include "qpid/RefCounted.h"
-#include "qpid/broker/AclModule.h"
-#include "qpid/sys/Mutex.h"
-
-#include <boost/intrusive_ptr.hpp>
-#include <string>
-#include <vector>
-
-namespace qpid {
-
-namespace sys {
- class ProtocolFactory;
- class Poller;
-}
-
-struct Url;
-
-namespace broker {
-
-class ConnectionState;
-class ExpiryPolicy;
-class Message;
-
-static const uint16_t DEFAULT_PORT=5672;
-
-struct NoSuchTransportException : qpid::Exception
-{
- NoSuchTransportException(const std::string& s) : Exception(s) {}
- virtual ~NoSuchTransportException() throw() {}
-};
-
-/**
- * A broker instance.
- */
-class Broker : public sys::Runnable, public Plugin::Target,
- public management::Manageable,
- public RefCounted
-{
-public:
-
- struct Options : public qpid::Options {
- static const std::string DEFAULT_DATA_DIR_LOCATION;
- static const std::string DEFAULT_DATA_DIR_NAME;
-
- QPID_BROKER_EXTERN Options(const std::string& name="Broker Options");
-
- bool noDataDir;
- std::string dataDir;
- uint16_t port;
- int workerThreads;
- int maxConnections;
- int connectionBacklog;
- bool enableMgmt;
- uint16_t mgmtPubInterval;
- uint16_t queueCleanInterval;
- bool auth;
- std::string realm;
- size_t replayFlushLimit;
- size_t replayHardLimit;
- uint queueLimit;
- bool tcpNoDelay;
- bool requireEncrypted;
- std::string knownHosts;
- std::string saslConfigPath;
- uint32_t maxSessionRate;
- bool asyncQueueEvents;
- bool qmf2Support;
- bool qmf1Support;
- uint queueFlowStopRatio; // producer flow control: on
- uint queueFlowResumeRatio; // producer flow control: off
- uint16_t queueThresholdEventRatio;
-
- private:
- std::string getHome();
- };
-
- class ConnectionCounter {
- int maxConnections;
- int connectionCount;
- sys::Mutex connectionCountLock;
- public:
- ConnectionCounter(int mc): maxConnections(mc),connectionCount(0) {};
- void inc_connectionCount() {
- sys::ScopedLock<sys::Mutex> l(connectionCountLock);
- connectionCount++;
- }
- void dec_connectionCount() {
- sys::ScopedLock<sys::Mutex> l(connectionCountLock);
- connectionCount--;
- }
- bool allowConnection() {
- sys::ScopedLock<sys::Mutex> l(connectionCountLock);
- return (maxConnections <= connectionCount);
- }
- };
-
- private:
- typedef std::map<std::string, boost::shared_ptr<sys::ProtocolFactory> > ProtocolFactoryMap;
-
- void declareStandardExchange(const std::string& name, const std::string& type);
- void setStore ();
- void setLogLevel(const std::string& level);
- std::string getLogLevel();
- void createObject(const std::string& type, const std::string& name,
- const qpid::types::Variant::Map& properties, bool strict, const ConnectionState* context);
- void deleteObject(const std::string& type, const std::string& name,
- const qpid::types::Variant::Map& options, const ConnectionState* context);
-
- boost::shared_ptr<sys::Poller> poller;
- sys::Timer timer;
- std::auto_ptr<sys::Timer> clusterTimer;
- Options config;
- std::auto_ptr<management::ManagementAgent> managementAgent;
- ProtocolFactoryMap protocolFactories;
- std::auto_ptr<MessageStore> store;
- AclModule* acl;
- DataDir dataDir;
-
- QueueRegistry queues;
- ExchangeRegistry exchanges;
- LinkRegistry links;
- boost::shared_ptr<sys::ConnectionCodec::Factory> factory;
- DtxManager dtxManager;
- SessionManager sessionManager;
- qmf::org::apache::qpid::broker::Broker* mgmtObject;
- Vhost::shared_ptr vhostObject;
- System::shared_ptr systemObject;
- QueueCleaner queueCleaner;
- QueueEvents queueEvents;
- std::vector<Url> knownBrokers;
- std::vector<Url> getKnownBrokersImpl();
- bool deferDeliveryImpl(const std::string& queue,
- const boost::intrusive_ptr<Message>& msg);
- std::string federationTag;
- bool recovery;
- bool inCluster, clusterUpdatee;
- boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
- ConnectionCounter connectionCounter;
-
- public:
- virtual ~Broker();
-
- QPID_BROKER_EXTERN Broker(const Options& configuration);
- static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(const Options& configuration);
- static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT);
-
- /**
- * Return listening port. If called before bind this is
- * the configured port. If called after it is the actual
- * port, which will be different if the configured port is
- * 0.
- */
- virtual uint16_t getPort(const std::string& name) const;
-
- /**
- * Run the broker. Implements Runnable::run() so the broker
- * can be run in a separate thread.
- */
- virtual void run();
-
- /** Shut down the broker */
- virtual void shutdown();
-
- QPID_BROKER_EXTERN void setStore (boost::shared_ptr<MessageStore>& store);
- MessageStore& getStore() { return *store; }
- void setAcl (AclModule* _acl) {acl = _acl;}
- AclModule* getAcl() { return acl; }
- QueueRegistry& getQueues() { return queues; }
- ExchangeRegistry& getExchanges() { return exchanges; }
- LinkRegistry& getLinks() { return links; }
- DtxManager& getDtxManager() { return dtxManager; }
- DataDir& getDataDir() { return dataDir; }
- Options& getOptions() { return config; }
- QueueEvents& getQueueEvents() { return queueEvents; }
-
- void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e) { expiryPolicy = e; }
- boost::intrusive_ptr<ExpiryPolicy> getExpiryPolicy() { return expiryPolicy; }
-
- SessionManager& getSessionManager() { return sessionManager; }
- const std::string& getFederationTag() const { return federationTag; }
-
- management::ManagementObject* GetManagementObject (void) const;
- management::Manageable* GetVhostObject (void) const;
- management::Manageable::status_t ManagementMethod (uint32_t methodId,
- management::Args& args,
- std::string& text);
-
- /** Add to the broker's protocolFactorys */
- void registerProtocolFactory(const std::string& name, boost::shared_ptr<sys::ProtocolFactory>);
-
- /** Accept connections */
- QPID_BROKER_EXTERN void accept();
-
- /** Create a connection to another broker. */
- void connect(const std::string& host, uint16_t port,
- const std::string& transport,
- boost::function2<void, int, std::string> failed,
- sys::ConnectionCodec::Factory* =0);
- /** Create a connection to another broker. */
- void connect(const Url& url,
- boost::function2<void, int, std::string> failed,
- sys::ConnectionCodec::Factory* =0);
-
- /** Move messages from one queue to another.
- A zero quantity means to move all messages
- */
- uint32_t queueMoveMessages( const std::string& srcQueue,
- const std::string& destQueue,
- uint32_t qty);
-
- boost::shared_ptr<sys::ProtocolFactory> getProtocolFactory(const std::string& name = TCP_TRANSPORT) const;
-
- /** Expose poller so plugins can register their descriptors. */
- boost::shared_ptr<sys::Poller> getPoller();
-
- boost::shared_ptr<sys::ConnectionCodec::Factory> getConnectionFactory() { return factory; }
- void setConnectionFactory(boost::shared_ptr<sys::ConnectionCodec::Factory> f) { factory = f; }
-
- /** Timer for local tasks affecting only this broker */
- sys::Timer& getTimer() { return timer; }
-
- /** Timer for tasks that must be synchronized if we are in a cluster */
- sys::Timer& getClusterTimer() { return clusterTimer.get() ? *clusterTimer : timer; }
- void setClusterTimer(std::auto_ptr<sys::Timer>);
-
- boost::function<std::vector<Url> ()> getKnownBrokers;
-
- static QPID_BROKER_EXTERN const std::string TCP_TRANSPORT;
-
- void setRecovery(bool set) { recovery = set; }
- bool getRecovery() const { return recovery; }
-
- /** True of this broker is part of a cluster.
- * Only valid after early initialization of plugins is complete.
- */
- bool isInCluster() const { return inCluster; }
- void setInCluster(bool set) { inCluster = set; }
-
- /** True if this broker is joining a cluster and in the process of
- * receiving a state update.
- */
- bool isClusterUpdatee() const { return clusterUpdatee; }
- void setClusterUpdatee(bool set) { clusterUpdatee = set; }
-
- management::ManagementAgent* getManagementAgent() { return managementAgent.get(); }
-
- ConnectionCounter& getConnectionCounter() {return connectionCounter;}
-
- /**
- * Never true in a stand-alone broker. In a cluster, return true
- * to defer delivery of messages deliveredg in a cluster-unsafe
- * context.
- *@return true if delivery of a message should be deferred.
- */
- boost::function<bool (const std::string& queue,
- const boost::intrusive_ptr<Message>& msg)> deferDelivery;
-
- bool isAuthenticating ( ) { return config.auth; }
-
- typedef boost::function1<void, boost::shared_ptr<Queue> > QueueFunctor;
-
- std::pair<boost::shared_ptr<Queue>, bool> createQueue(
- const std::string& name,
- bool durable,
- bool autodelete,
- const OwnershipToken* owner,
- const std::string& alternateExchange,
- const qpid::framing::FieldTable& arguments,
- const std::string& userId,
- const std::string& connectionId);
- void deleteQueue(const std::string& name,
- const std::string& userId,
- const std::string& connectionId,
- QueueFunctor check = QueueFunctor());
- std::pair<Exchange::shared_ptr, bool> createExchange(
- const std::string& name,
- const std::string& type,
- bool durable,
- const std::string& alternateExchange,
- const qpid::framing::FieldTable& args,
- const std::string& userId, const std::string& connectionId);
- void deleteExchange(const std::string& name, const std::string& userId,
- const std::string& connectionId);
- void bind(const std::string& queue,
- const std::string& exchange,
- const std::string& key,
- const qpid::framing::FieldTable& arguments,
- const std::string& userId,
- const std::string& connectionId);
- void unbind(const std::string& queue,
- const std::string& exchange,
- const std::string& key,
- const std::string& userId,
- const std::string& connectionId);
-};
-
-}}
-
-#endif /*!_Broker_*/
diff --git a/cpp/src/qpid/broker/BrokerImportExport.h b/cpp/src/qpid/broker/BrokerImportExport.h
deleted file mode 100644
index ee05788063..0000000000
--- a/cpp/src/qpid/broker/BrokerImportExport.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef QPID_BROKER_IMPORT_EXPORT_H
-#define QPID_BROKER_IMPORT_EXPORT_H
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
-# if defined(BROKER_EXPORT) || defined (qpidbroker_EXPORTS)
-# define QPID_BROKER_EXTERN __declspec(dllexport)
-# else
-# define QPID_BROKER_EXTERN __declspec(dllimport)
-# endif
-# ifdef _MSC_VER
-# define QPID_BROKER_CLASS_EXTERN
-# define QPID_BROKER_INLINE_EXTERN QPID_BROKER_EXTERN
-# else
-# define QPID_BROKER_CLASS_EXTERN QPID_BROKER_EXTERN
-# define QPID_BROKER_INLINE_EXTERN
-# endif
-#else
-# define QPID_BROKER_EXTERN
-# define QPID_BROKER_CLASS_EXTERN
-# define QPID_BROKER_INLINE_EXTERN
-#endif
-
-#endif
diff --git a/cpp/src/qpid/broker/Connection.cpp b/cpp/src/qpid/broker/Connection.cpp
deleted file mode 100644
index c07e63e68c..0000000000
--- a/cpp/src/qpid/broker/Connection.cpp
+++ /dev/null
@@ -1,487 +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.
- *
- */
-#include "qpid/broker/Connection.h"
-#include "qpid/broker/SessionOutputException.h"
-#include "qpid/broker/SessionState.h"
-#include "qpid/broker/Bridge.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/sys/SecuritySettings.h"
-#include "qpid/sys/ClusterSafe.h"
-
-#include "qpid/log/Statement.h"
-#include "qpid/ptr_map.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-#include "qpid/framing/enum.h"
-#include "qpid/framing/MessageTransferBody.h"
-#include "qmf/org/apache/qpid/broker/EventClientConnect.h"
-#include "qmf/org/apache/qpid/broker/EventClientDisconnect.h"
-
-#include <boost/bind.hpp>
-#include <boost/ptr_container/ptr_vector.hpp>
-
-#include <algorithm>
-#include <iostream>
-#include <assert.h>
-
-
-
-using namespace qpid::sys;
-using namespace qpid::framing;
-using qpid::ptr_map_ptr;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace qpid {
-namespace broker {
-
-struct ConnectionTimeoutTask : public sys::TimerTask {
- sys::Timer& timer;
- Connection& connection;
-
- ConnectionTimeoutTask(uint16_t hb, sys::Timer& t, Connection& c) :
- TimerTask(Duration(hb*2*TIME_SEC),"ConnectionTimeout"),
- timer(t),
- connection(c)
- {}
-
- void touch() {
- restart();
- }
-
- void fire() {
- // If we get here then we've not received any traffic in the timeout period
- // Schedule closing the connection for the io thread
- QPID_LOG(error, "Connection " << connection.getMgmtId()
- << " timed out: closing");
- connection.abort();
- }
-};
-
-Connection::Connection(ConnectionOutputHandler* out_,
- Broker& broker_, const
- std::string& mgmtId_,
- const qpid::sys::SecuritySettings& external,
- bool isLink_,
- uint64_t objectId_,
- bool shadow_,
- bool delayManagement) :
- ConnectionState(out_, broker_),
- securitySettings(external),
- adapter(*this, isLink_, shadow_),
- isLink(isLink_),
- mgmtClosing(false),
- mgmtId(mgmtId_),
- mgmtObject(0),
- links(broker_.getLinks()),
- agent(0),
- timer(broker_.getTimer()),
- errorListener(0),
- objectId(objectId_),
- shadow(shadow_),
- outboundTracker(*this)
-{
- outboundTracker.wrap(out);
- if (isLink)
- links.notifyConnection(mgmtId, this);
- // In a cluster, allow adding the management object to be delayed.
- if (!delayManagement) addManagementObject();
- if (!isShadow()) broker.getConnectionCounter().inc_connectionCount();
-}
-
-void Connection::addManagementObject() {
- assert(agent == 0);
- assert(mgmtObject == 0);
- Manageable* parent = broker.GetVhostObject();
- if (parent != 0) {
- agent = broker.getManagementAgent();
- if (agent != 0) {
- // TODO set last bool true if system connection
- mgmtObject = new _qmf::Connection(agent, this, parent, mgmtId, !isLink, false);
- mgmtObject->set_shadow(shadow);
- agent->addObject(mgmtObject, objectId);
- }
- ConnectionState::setUrl(mgmtId);
- }
-}
-
-void Connection::requestIOProcessing(boost::function0<void> callback)
-{
- ScopedLock<Mutex> l(ioCallbackLock);
- ioCallbacks.push(callback);
- out.activateOutput();
-}
-
-Connection::~Connection()
-{
- if (mgmtObject != 0) {
- mgmtObject->resourceDestroy();
- // In a cluster, Connections destroyed during shutdown are in
- // a cluster-unsafe context. Don't raise an event in that case.
- if (!isLink && isClusterSafe())
- agent->raiseEvent(_qmf::EventClientDisconnect(mgmtId, ConnectionState::getUserId()));
- }
- if (isLink)
- links.notifyClosed(mgmtId);
-
- if (heartbeatTimer)
- heartbeatTimer->cancel();
- if (timeoutTimer)
- timeoutTimer->cancel();
-
- if (!isShadow()) broker.getConnectionCounter().dec_connectionCount();
-}
-
-void Connection::received(framing::AMQFrame& frame) {
- // Received frame on connection so delay timeout
- restartTimeout();
-
- if (frame.getChannel() == 0 && frame.getMethod()) {
- adapter.handle(frame);
- } else {
- if (adapter.isOpen())
- getChannel(frame.getChannel()).in(frame);
- else
- close(connection::CLOSE_CODE_FRAMING_ERROR, "Connection not yet open, invalid frame received.");
- }
-
- if (isLink) //i.e. we are acting as the client to another broker
- recordFromServer(frame);
- else
- recordFromClient(frame);
-}
-
-void Connection::sent(const framing::AMQFrame& frame)
-{
- if (isLink) //i.e. we are acting as the client to another broker
- recordFromClient(frame);
- else
- recordFromServer(frame);
-}
-
-bool isMessage(const AMQMethodBody* method)
-{
- return method && method->isA<qpid::framing::MessageTransferBody>();
-}
-
-void Connection::recordFromServer(const framing::AMQFrame& frame)
-{
- // Don't record management stats in cluster-unsafe contexts
- if (mgmtObject != 0 && isClusterSafe())
- {
- mgmtObject->inc_framesToClient();
- mgmtObject->inc_bytesToClient(frame.encodedSize());
- if (isMessage(frame.getMethod())) {
- mgmtObject->inc_msgsToClient();
- }
- }
-}
-
-void Connection::recordFromClient(const framing::AMQFrame& frame)
-{
- // Don't record management stats in cluster-unsafe contexts
- if (mgmtObject != 0 && isClusterSafe())
- {
- mgmtObject->inc_framesFromClient();
- mgmtObject->inc_bytesFromClient(frame.encodedSize());
- if (isMessage(frame.getMethod())) {
- mgmtObject->inc_msgsFromClient();
- }
- }
-}
-
-string Connection::getAuthMechanism()
-{
- if (!isLink)
- return string("ANONYMOUS");
-
- return links.getAuthMechanism(mgmtId);
-}
-
-string Connection::getUsername ( )
-{
- if (!isLink)
- return string("anonymous");
-
- return links.getUsername(mgmtId);
-}
-
-string Connection::getPassword ( )
-{
- if (!isLink)
- return string("");
-
- return links.getPassword(mgmtId);
-}
-
-string Connection::getHost ( )
-{
- if (!isLink)
- return string("");
-
- return links.getHost(mgmtId);
-}
-
-uint16_t Connection::getPort ( )
-{
- if (!isLink)
- return 0;
-
- return links.getPort(mgmtId);
-}
-
-string Connection::getAuthCredentials()
-{
- if (!isLink)
- return string();
-
- if (mgmtObject != 0)
- {
- if (links.getAuthMechanism(mgmtId) == "ANONYMOUS")
- mgmtObject->set_authIdentity("anonymous");
- else
- mgmtObject->set_authIdentity(links.getAuthIdentity(mgmtId));
- }
-
- return links.getAuthCredentials(mgmtId);
-}
-
-void Connection::notifyConnectionForced(const string& text)
-{
- if (isLink)
- links.notifyConnectionForced(mgmtId, text);
-}
-
-void Connection::setUserId(const string& userId)
-{
- ConnectionState::setUserId(userId);
- // In a cluster, the cluster code will raise the connect event
- // when the connection is replicated to the cluster.
- if (!broker.isInCluster()) raiseConnectEvent();
-}
-
-void Connection::raiseConnectEvent() {
- if (mgmtObject != 0) {
- mgmtObject->set_authIdentity(userId);
- agent->raiseEvent(_qmf::EventClientConnect(mgmtId, userId));
- }
-}
-
-void Connection::setFederationLink(bool b)
-{
- ConnectionState::setFederationLink(b);
- if (mgmtObject != 0)
- mgmtObject->set_federationLink(b);
-}
-
-void Connection::close(connection::CloseCode code, const string& text)
-{
- QPID_LOG_IF(error, code != connection::CLOSE_CODE_NORMAL, "Connection " << mgmtId << " closed by error: " << text << "(" << code << ")");
- if (heartbeatTimer)
- heartbeatTimer->cancel();
- if (timeoutTimer)
- timeoutTimer->cancel();
- adapter.close(code, text);
- //make sure we delete dangling pointers from outputTasks before deleting sessions
- outputTasks.removeAll();
- channels.clear();
- getOutput().close();
-}
-
-// Send a close to the client but keep the channels. Used by cluster.
-void Connection::sendClose() {
- if (heartbeatTimer)
- heartbeatTimer->cancel();
- if (timeoutTimer)
- timeoutTimer->cancel();
- adapter.close(connection::CLOSE_CODE_NORMAL, "OK");
- getOutput().close();
-}
-
-void Connection::idleOut(){}
-
-void Connection::idleIn(){}
-
-void Connection::closed(){ // Physically closed, suspend open sessions.
- if (heartbeatTimer)
- heartbeatTimer->cancel();
- if (timeoutTimer)
- timeoutTimer->cancel();
- try {
- while (!channels.empty())
- ptr_map_ptr(channels.begin())->handleDetach();
- } catch(std::exception& e) {
- QPID_LOG(error, QPID_MSG("While closing connection: " << e.what()));
- assert(0);
- }
-}
-
-void Connection::doIoCallbacks() {
- {
- ScopedLock<Mutex> l(ioCallbackLock);
- // Although IO callbacks execute in the connection thread context, they are
- // not cluster safe because they are queued for execution in non-IO threads.
- ClusterUnsafeScope cus;
- while (!ioCallbacks.empty()) {
- boost::function0<void> cb = ioCallbacks.front();
- ioCallbacks.pop();
- ScopedUnlock<Mutex> ul(ioCallbackLock);
- cb(); // Lend the IO thread for management processing
- }
- }
-}
-
-bool Connection::doOutput() {
- try {
- doIoCallbacks();
- if (mgmtClosing) {
- closed();
- close(connection::CLOSE_CODE_CONNECTION_FORCED, "Closed by Management Request");
- } else {
- //then do other output as needed:
- return outputTasks.doOutput();
- }
- }catch(const SessionOutputException& e){
- getChannel(e.channel).handleException(e);
- return true;
- }catch(ConnectionException& e){
- close(e.code, e.getMessage());
- }catch(std::exception& e){
- close(connection::CLOSE_CODE_CONNECTION_FORCED, e.what());
- }
- return false;
-}
-
-void Connection::sendHeartbeat() {
- adapter.heartbeat();
-}
-
-void Connection::closeChannel(uint16_t id) {
- ChannelMap::iterator i = channels.find(id);
- if (i != channels.end()) channels.erase(i);
-}
-
-SessionHandler& Connection::getChannel(ChannelId id) {
- ChannelMap::iterator i=channels.find(id);
- if (i == channels.end()) {
- i = channels.insert(id, new SessionHandler(*this, id)).first;
- }
- return *ptr_map_ptr(i);
-}
-
-ManagementObject* Connection::GetManagementObject(void) const
-{
- return (ManagementObject*) mgmtObject;
-}
-
-Manageable::status_t Connection::ManagementMethod(uint32_t methodId, Args&, string&)
-{
- Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD;
-
- QPID_LOG(debug, "Connection::ManagementMethod [id=" << methodId << "]");
-
- switch (methodId)
- {
- case _qmf::Connection::METHOD_CLOSE :
- mgmtClosing = true;
- if (mgmtObject != 0) mgmtObject->set_closing(1);
- out.activateOutput();
- status = Manageable::STATUS_OK;
- break;
- }
-
- return status;
-}
-
-void Connection::setSecureConnection(SecureConnection* s)
-{
- adapter.setSecureConnection(s);
-}
-
-struct ConnectionHeartbeatTask : public sys::TimerTask {
- sys::Timer& timer;
- Connection& connection;
- ConnectionHeartbeatTask(uint16_t hb, sys::Timer& t, Connection& c) :
- TimerTask(Duration(hb*TIME_SEC), "ConnectionHeartbeat"),
- timer(t),
- connection(c)
- {}
-
- void fire() {
- // Setup next firing
- setupNextFire();
- timer.add(this);
-
- // Send Heartbeat
- connection.sendHeartbeat();
- }
-};
-
-void Connection::abort()
-{
- // Make sure that we don't try to send a heartbeat as we're
- // aborting the connection
- if (heartbeatTimer)
- heartbeatTimer->cancel();
-
- out.abort();
-}
-
-void Connection::setHeartbeatInterval(uint16_t heartbeat)
-{
- setHeartbeat(heartbeat);
- if (heartbeat > 0 && !isShadow()) {
- heartbeatTimer = new ConnectionHeartbeatTask(heartbeat, timer, *this);
- timer.add(heartbeatTimer);
- timeoutTimer = new ConnectionTimeoutTask(heartbeat, timer, *this);
- timer.add(timeoutTimer);
- }
-}
-
-void Connection::restartTimeout()
-{
- if (timeoutTimer)
- timeoutTimer->touch();
-}
-
-bool Connection::isOpen() { return adapter.isOpen(); }
-
-Connection::OutboundFrameTracker::OutboundFrameTracker(Connection& _con) : con(_con), next(0) {}
-void Connection::OutboundFrameTracker::close() { next->close(); }
-size_t Connection::OutboundFrameTracker::getBuffered() const { return next->getBuffered(); }
-void Connection::OutboundFrameTracker::abort() { next->abort(); }
-void Connection::OutboundFrameTracker::activateOutput() { next->activateOutput(); }
-void Connection::OutboundFrameTracker::giveReadCredit(int32_t credit) { next->giveReadCredit(credit); }
-void Connection::OutboundFrameTracker::send(framing::AMQFrame& f)
-{
- next->send(f);
- con.sent(f);
-}
-void Connection::OutboundFrameTracker::wrap(sys::ConnectionOutputHandlerPtr& p)
-{
- next = p.get();
- p.set(this);
-}
-
-}}
diff --git a/cpp/src/qpid/broker/Connection.h b/cpp/src/qpid/broker/Connection.h
deleted file mode 100644
index 8f1aa701ef..0000000000
--- a/cpp/src/qpid/broker/Connection.h
+++ /dev/null
@@ -1,216 +0,0 @@
-#ifndef QPID_BROKER_CONNECTION_H
-#define QPID_BROKER_CONNECTION_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <memory>
-#include <sstream>
-#include <vector>
-#include <queue>
-
-#include <boost/ptr_container/ptr_map.hpp>
-
-#include "qpid/broker/ConnectionHandler.h"
-#include "qpid/broker/ConnectionState.h"
-#include "qpid/broker/SessionHandler.h"
-#include "qmf/org/apache/qpid/broker/Connection.h"
-#include "qpid/Exception.h"
-#include "qpid/RefCounted.h"
-#include "qpid/framing/AMQFrame.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-#include "qpid/framing/AMQP_ServerOperations.h"
-#include "qpid/framing/ProtocolVersion.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/management/Manageable.h"
-#include "qpid/ptr_map.h"
-#include "qpid/sys/AggregateOutput.h"
-#include "qpid/sys/ConnectionInputHandler.h"
-#include "qpid/sys/ConnectionOutputHandler.h"
-#include "qpid/sys/SecuritySettings.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/TimeoutHandler.h"
-#include "qpid/sys/Mutex.h"
-
-#include <boost/ptr_container/ptr_map.hpp>
-#include <boost/bind.hpp>
-
-#include <algorithm>
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-class LinkRegistry;
-class SecureConnection;
-struct ConnectionTimeoutTask;
-
-class Connection : public sys::ConnectionInputHandler,
- public ConnectionState,
- public RefCounted
-{
- public:
- /**
- * Listener that can be registered with a Connection to be informed of errors.
- */
- class ErrorListener
- {
- public:
- virtual ~ErrorListener() {}
- virtual void sessionError(uint16_t channel, const std::string&) = 0;
- virtual void connectionError(const std::string&) = 0;
- };
-
- Connection(sys::ConnectionOutputHandler* out,
- Broker& broker,
- const std::string& mgmtId,
- const qpid::sys::SecuritySettings&,
- bool isLink = false,
- uint64_t objectId = 0,
- bool shadow=false,
- bool delayManagement = false);
-
- ~Connection ();
-
- /** Get the SessionHandler for channel. Create if it does not already exist */
- SessionHandler& getChannel(framing::ChannelId channel);
-
- /** Close the connection */
- void close(framing::connection::CloseCode code, const std::string& text);
-
- // ConnectionInputHandler methods
- void received(framing::AMQFrame& frame);
- void idleOut();
- void idleIn();
- bool doOutput();
- void closed();
-
- void closeChannel(framing::ChannelId channel);
-
- // Manageable entry points
- management::ManagementObject* GetManagementObject (void) const;
- management::Manageable::status_t
- ManagementMethod (uint32_t methodId, management::Args& args, std::string&);
-
- void requestIOProcessing (boost::function0<void>);
- void recordFromServer (const framing::AMQFrame& frame);
- void recordFromClient (const framing::AMQFrame& frame);
- std::string getAuthMechanism();
- std::string getAuthCredentials();
- std::string getUsername();
- std::string getPassword();
- std::string getHost();
- uint16_t getPort();
- void notifyConnectionForced(const std::string& text);
- void setUserId(const std::string& uid);
- void raiseConnectEvent();
- const std::string& getUserId() const { return ConnectionState::getUserId(); }
- const std::string& getMgmtId() const { return mgmtId; }
- management::ManagementAgent* getAgent() const { return agent; }
- void setFederationLink(bool b);
- /** Connection does not delete the listener. 0 resets. */
- void setErrorListener(ErrorListener* l) { errorListener=l; }
- ErrorListener* getErrorListener() { return errorListener; }
-
- void setHeartbeatInterval(uint16_t heartbeat);
- void sendHeartbeat();
- void restartTimeout();
- void abort();
-
- template <class F> void eachSessionHandler(F f) {
- for (ChannelMap::iterator i = channels.begin(); i != channels.end(); ++i)
- f(*ptr_map_ptr(i));
- }
-
- void sendClose();
- void setSecureConnection(SecureConnection* secured);
-
- /** True if this is a shadow connection in a cluster. */
- bool isShadow() { return shadow; }
-
- // Used by cluster to update connection status
- sys::AggregateOutput& getOutputTasks() { return outputTasks; }
-
- /** Cluster delays adding management object in the constructor then calls this. */
- void addManagementObject();
-
- const qpid::sys::SecuritySettings& getExternalSecuritySettings() const
- {
- return securitySettings;
- }
-
- /** @return true if the initial connection negotiation is complete. */
- bool isOpen();
-
- // Used by cluster during catch-up, see cluster::OutputInterceptor
- void doIoCallbacks();
-
- private:
- typedef boost::ptr_map<framing::ChannelId, SessionHandler> ChannelMap;
- typedef std::vector<boost::shared_ptr<Queue> >::iterator queue_iterator;
-
- ChannelMap channels;
- qpid::sys::SecuritySettings securitySettings;
- ConnectionHandler adapter;
- const bool isLink;
- bool mgmtClosing;
- const std::string mgmtId;
- sys::Mutex ioCallbackLock;
- std::queue<boost::function0<void> > ioCallbacks;
- qmf::org::apache::qpid::broker::Connection* mgmtObject;
- LinkRegistry& links;
- management::ManagementAgent* agent;
- sys::Timer& timer;
- boost::intrusive_ptr<sys::TimerTask> heartbeatTimer;
- boost::intrusive_ptr<ConnectionTimeoutTask> timeoutTimer;
- ErrorListener* errorListener;
- uint64_t objectId;
- bool shadow;
- /**
- * Chained ConnectionOutputHandler that allows outgoing frames to be
- * tracked (for updating mgmt stats).
- */
- class OutboundFrameTracker : public sys::ConnectionOutputHandler
- {
- public:
- OutboundFrameTracker(Connection&);
- void close();
- size_t getBuffered() const;
- void abort();
- void activateOutput();
- void giveReadCredit(int32_t credit);
- void send(framing::AMQFrame&);
- void wrap(sys::ConnectionOutputHandlerPtr&);
- private:
- Connection& con;
- sys::ConnectionOutputHandler* next;
- };
- OutboundFrameTracker outboundTracker;
-
-
- void sent(const framing::AMQFrame& f);
- public:
- qmf::org::apache::qpid::broker::Connection* getMgmtObject() { return mgmtObject; }
-};
-
-}}
-
-#endif /*!QPID_BROKER_CONNECTION_H*/
diff --git a/cpp/src/qpid/broker/ConnectionFactory.cpp b/cpp/src/qpid/broker/ConnectionFactory.cpp
deleted file mode 100644
index 9e0020812b..0000000000
--- a/cpp/src/qpid/broker/ConnectionFactory.cpp
+++ /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.
- *
- */
-#include "qpid/broker/ConnectionFactory.h"
-#include "qpid/framing/ProtocolVersion.h"
-#include "qpid/amqp_0_10/Connection.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/sys/SecuritySettings.h"
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace broker {
-
-using framing::ProtocolVersion;
-using qpid::sys::SecuritySettings;
-typedef std::auto_ptr<amqp_0_10::Connection> ConnectionPtr;
-typedef std::auto_ptr<sys::ConnectionInputHandler> InputPtr;
-
-ConnectionFactory::ConnectionFactory(Broker& b) : broker(b) {}
-
-ConnectionFactory::~ConnectionFactory() {}
-
-sys::ConnectionCodec*
-ConnectionFactory::create(ProtocolVersion v, sys::OutputControl& out, const std::string& id,
- const SecuritySettings& external) {
- if (broker.getConnectionCounter().allowConnection())
- {
- QPID_LOG(error, "Client max connection count limit exceeded: " << broker.getOptions().maxConnections << " connection refused");
- return 0;
- }
- if (v == ProtocolVersion(0, 10)) {
- ConnectionPtr c(new amqp_0_10::Connection(out, id, false));
- c->setInputHandler(InputPtr(new broker::Connection(c.get(), broker, id, external, false)));
- return c.release();
- }
- return 0;
-}
-
-sys::ConnectionCodec*
-ConnectionFactory::create(sys::OutputControl& out, const std::string& id,
- const SecuritySettings& external) {
- // used to create connections from one broker to another
- ConnectionPtr c(new amqp_0_10::Connection(out, id, true));
- c->setInputHandler(InputPtr(new broker::Connection(c.get(), broker, id, external, true)));
- return c.release();
-}
-
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/ConnectionFactory.h b/cpp/src/qpid/broker/ConnectionFactory.h
deleted file mode 100644
index 7c1a9a08e1..0000000000
--- a/cpp/src/qpid/broker/ConnectionFactory.h
+++ /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.
- *
- */
-#ifndef _ConnectionFactory_
-#define _ConnectionFactory_
-
-#include "qpid/sys/ConnectionCodec.h"
-
-namespace qpid {
-namespace broker {
-class Broker;
-
-class ConnectionFactory : public sys::ConnectionCodec::Factory
-{
- public:
- ConnectionFactory(Broker& b);
-
- virtual ~ConnectionFactory();
-
- sys::ConnectionCodec*
- create(framing::ProtocolVersion, sys::OutputControl&, const std::string& id,
- const qpid::sys::SecuritySettings&);
-
- sys::ConnectionCodec*
- create(sys::OutputControl&, const std::string& id, const qpid::sys::SecuritySettings&);
-
- private:
- Broker& broker;
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/ConnectionHandler.cpp b/cpp/src/qpid/broker/ConnectionHandler.cpp
deleted file mode 100644
index 3f97e5b9de..0000000000
--- a/cpp/src/qpid/broker/ConnectionHandler.cpp
+++ /dev/null
@@ -1,364 +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.
- *
- */
-
-#include "qpid/SaslFactory.h"
-#include "qpid/broker/ConnectionHandler.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/broker/SecureConnection.h"
-#include "qpid/Url.h"
-#include "qpid/framing/AllInvoker.h"
-#include "qpid/framing/enum.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/SecurityLayer.h"
-#include "qpid/broker/AclModule.h"
-#include "qmf/org/apache/qpid/broker/EventClientConnectFail.h"
-
-using namespace qpid;
-using namespace qpid::broker;
-using namespace qpid::framing;
-using qpid::sys::SecurityLayer;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace
-{
-const std::string ANONYMOUS = "ANONYMOUS";
-const std::string PLAIN = "PLAIN";
-const std::string en_US = "en_US";
-const std::string QPID_FED_LINK = "qpid.fed_link";
-const std::string QPID_FED_TAG = "qpid.federation_tag";
-const std::string SESSION_FLOW_CONTROL("qpid.session_flow");
-const std::string CLIENT_PROCESS_NAME("qpid.client_process");
-const std::string CLIENT_PID("qpid.client_pid");
-const std::string CLIENT_PPID("qpid.client_ppid");
-const int SESSION_FLOW_CONTROL_VER = 1;
-const std::string SPACE(" ");
-}
-
-void ConnectionHandler::close(connection::CloseCode code, const string& text)
-{
- handler->proxy.close(code, text);
-}
-
-void ConnectionHandler::heartbeat()
-{
- handler->proxy.heartbeat();
-}
-
-void ConnectionHandler::handle(framing::AMQFrame& frame)
-{
- AMQMethodBody* method=frame.getBody()->getMethod();
- Connection::ErrorListener* errorListener = handler->connection.getErrorListener();
- try{
- if (!invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler.get()), *method)) {
- handler->connection.getChannel(frame.getChannel()).in(frame);
- }
- }catch(ConnectionException& e){
- if (errorListener) errorListener->connectionError(e.what());
- handler->proxy.close(e.code, e.what());
- }catch(std::exception& e){
- if (errorListener) errorListener->connectionError(e.what());
- handler->proxy.close(541/*internal error*/, e.what());
- }
-}
-
-void ConnectionHandler::setSecureConnection(SecureConnection* secured)
-{
- handler->secured = secured;
-}
-
-ConnectionHandler::ConnectionHandler(Connection& connection, bool isClient, bool isShadow) : handler(new Handler(connection, isClient, isShadow)) {}
-
-ConnectionHandler::Handler::Handler(Connection& c, bool isClient, bool isShadow) :
- proxy(c.getOutput()),
- connection(c), serverMode(!isClient), acl(0), secured(0),
- isOpen(false)
-{
- if (serverMode) {
-
- acl = connection.getBroker().getAcl();
-
- FieldTable properties;
- Array mechanisms(0x95);
-
- properties.setString(QPID_FED_TAG, connection.getBroker().getFederationTag());
-
- authenticator = SaslAuthenticator::createAuthenticator(c, isShadow);
- authenticator->getMechanisms(mechanisms);
-
- Array locales(0x95);
- boost::shared_ptr<FieldValue> l(new Str16Value(en_US));
- locales.add(l);
- proxy.start(properties, mechanisms, locales);
-
- }
-
- maxFrameSize = (64 * 1024) - 1;
-}
-
-
-ConnectionHandler::Handler::~Handler() {}
-
-
-void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProperties,
- const string& mechanism,
- const string& response,
- const string& /*locale*/)
-{
- try {
- authenticator->start(mechanism, response);
- } catch (std::exception& /*e*/) {
- management::ManagementAgent* agent = connection.getAgent();
- if (agent) {
- string error;
- string uid;
- authenticator->getError(error);
- authenticator->getUid(uid);
- agent->raiseEvent(_qmf::EventClientConnectFail(connection.getMgmtId(), uid, error));
- }
- throw;
- }
- connection.setFederationLink(clientProperties.get(QPID_FED_LINK));
- connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
- if (connection.isFederationLink()) {
- if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){
- proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
- return;
- }
- QPID_LOG(info, "Connection is a federation link");
- }
- if (clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER) {
- connection.setClientThrottling();
- }
-
- if (connection.getMgmtObject() != 0) {
- string procName = clientProperties.getAsString(CLIENT_PROCESS_NAME);
- uint32_t pid = clientProperties.getAsInt(CLIENT_PID);
- uint32_t ppid = clientProperties.getAsInt(CLIENT_PPID);
-
- if (!procName.empty())
- connection.getMgmtObject()->set_remoteProcessName(procName);
- if (pid != 0)
- connection.getMgmtObject()->set_remotePid(pid);
- if (ppid != 0)
- connection.getMgmtObject()->set_remoteParentPid(ppid);
- }
-}
-
-void ConnectionHandler::Handler::secureOk(const string& response)
-{
- try {
- authenticator->step(response);
- } catch (std::exception& /*e*/) {
- management::ManagementAgent* agent = connection.getAgent();
- if (agent) {
- string error;
- string uid;
- authenticator->getError(error);
- authenticator->getUid(uid);
- agent->raiseEvent(_qmf::EventClientConnectFail(connection.getMgmtId(), uid, error));
- }
- throw;
- }
-}
-
-void ConnectionHandler::Handler::tuneOk(uint16_t /*channelmax*/,
- uint16_t framemax, uint16_t heartbeat)
-{
- connection.setFrameMax(framemax);
- connection.setHeartbeatInterval(heartbeat);
-}
-
-void ConnectionHandler::Handler::open(const string& /*virtualHost*/,
- const framing::Array& /*capabilities*/, bool /*insist*/)
-{
- std::vector<Url> urls = connection.broker.getKnownBrokers();
- framing::Array array(0x95); // str16 array
- for (std::vector<Url>::iterator i = urls.begin(); i < urls.end(); ++i)
- array.add(boost::shared_ptr<Str16Value>(new Str16Value(i->str())));
-
- //install security layer if one has been negotiated:
- if (secured) {
- std::auto_ptr<SecurityLayer> sl = authenticator->getSecurityLayer(connection.getFrameMax());
- if (sl.get()) secured->activateSecurityLayer(sl);
- }
-
- isOpen = true;
- proxy.openOk(array);
-}
-
-
-void ConnectionHandler::Handler::close(uint16_t replyCode, const string& replyText)
-{
- if (replyCode != 200) {
- QPID_LOG(warning, "Client closed connection with " << replyCode << ": " << replyText);
- }
-
- if (replyCode == framing::connection::CLOSE_CODE_CONNECTION_FORCED)
- connection.notifyConnectionForced(replyText);
-
- proxy.closeOk();
- connection.getOutput().close();
-}
-
-void ConnectionHandler::Handler::closeOk(){
- connection.getOutput().close();
-}
-
-void ConnectionHandler::Handler::heartbeat(){
- // For general case, do nothing - the purpose of heartbeats is
- // just to make sure that there is some traffic on the connection
- // within the heart beat interval, we check for the traffic and
- // don't need to do anything in response to heartbeats. The
- // exception is when we are in fact the client to another broker
- // (i.e. an inter-broker link), in which case we echo the
- // heartbeat back to the peer
- if (!serverMode) proxy.heartbeat();
-}
-
-void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
- const framing::Array& supportedMechanisms,
- const framing::Array& /*locales*/)
-{
- string requestedMechanism = connection.getAuthMechanism();
-
- std::string username = connection.getUsername();
-
- std::string password = connection.getPassword();
- std::string host = connection.getHost();
- std::string service("qpidd");
-
- if ( connection.getBroker().isAuthenticating() ) {
- sasl = SaslFactory::getInstance().create( username,
- password,
- service,
- host,
- 0, // TODO -- mgoulish Fri Sep 24 2010
- 256,
- false ); // disallow interaction
- }
- std::string supportedMechanismsList;
- bool requestedMechanismIsSupported = false;
- Array::const_iterator i;
-
- /*
- If no specific mechanism has been requested, just make
- a list of all of them, and assert that the one the caller
- requested is there. ( If *any* are supported! )
- */
- if ( requestedMechanism.empty() ) {
- for ( i = supportedMechanisms.begin(); i != supportedMechanisms.end(); ++i) {
- if (i != supportedMechanisms.begin())
- supportedMechanismsList += SPACE;
- supportedMechanismsList += (*i)->get<std::string>();
- requestedMechanismIsSupported = true;
- }
- }
- else {
- requestedMechanismIsSupported = false;
- /*
- The caller has requested a mechanism. If it's available,
- make sure it ends up at the head of the list.
- */
- for ( i = supportedMechanisms.begin(); i != supportedMechanisms.end(); ++i) {
- string currentMechanism = (*i)->get<std::string>();
-
- if ( requestedMechanism == currentMechanism ) {
- requestedMechanismIsSupported = true;
- supportedMechanismsList = currentMechanism + SPACE + supportedMechanismsList;
- } else {
- if (i != supportedMechanisms.begin())
- supportedMechanismsList += SPACE;
- supportedMechanismsList += currentMechanism;
- }
- }
- }
-
- connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG));
-
- FieldTable ft;
- ft.setInt(QPID_FED_LINK,1);
- ft.setString(QPID_FED_TAG, connection.getBroker().getFederationTag());
-
- string response;
- if (sasl.get()) {
- const qpid::sys::SecuritySettings& ss = connection.getExternalSecuritySettings();
- response = sasl->start ( requestedMechanism.empty()
- ? supportedMechanismsList
- : requestedMechanism,
- & ss );
- proxy.startOk ( ft, sasl->getMechanism(), response, en_US );
- }
- else {
- response = ((char)0) + username + ((char)0) + password;
- proxy.startOk ( ft, requestedMechanism, response, en_US );
- }
-
-}
-
-void ConnectionHandler::Handler::secure(const string& challenge )
-{
- if (sasl.get()) {
- string response = sasl->step(challenge);
- proxy.secureOk(response);
- }
- else {
- proxy.secureOk("");
- }
-}
-
-void ConnectionHandler::Handler::tune(uint16_t channelMax,
- uint16_t maxFrameSizeProposed,
- uint16_t /*heartbeatMin*/,
- uint16_t heartbeatMax)
-{
- maxFrameSize = std::min(maxFrameSize, maxFrameSizeProposed);
- connection.setFrameMax(maxFrameSize);
-
- connection.setHeartbeat(heartbeatMax);
- proxy.tuneOk(channelMax, maxFrameSize, heartbeatMax);
- proxy.open("/", Array(), true);
-}
-
-void ConnectionHandler::Handler::openOk(const framing::Array& knownHosts)
-{
- for (Array::ValueVector::const_iterator i = knownHosts.begin(); i != knownHosts.end(); ++i) {
- Url url((*i)->get<std::string>());
- connection.getKnownHosts().push_back(url);
- }
-
- if (sasl.get()) {
- std::auto_ptr<qpid::sys::SecurityLayer> securityLayer = sasl->getSecurityLayer(maxFrameSize);
-
- if ( securityLayer.get() ) {
- secured->activateSecurityLayer(securityLayer, true);
- }
-
- saslUserId = sasl->getUserId();
- }
-
- isOpen = true;
-}
-
-void ConnectionHandler::Handler::redirect(const string& /*host*/, const framing::Array& /*knownHosts*/)
-{
-
-}
diff --git a/cpp/src/qpid/broker/ConnectionHandler.h b/cpp/src/qpid/broker/ConnectionHandler.h
deleted file mode 100644
index b32167669e..0000000000
--- a/cpp/src/qpid/broker/ConnectionHandler.h
+++ /dev/null
@@ -1,112 +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.
- *
- */
-#ifndef _ConnectionAdapter_
-#define _ConnectionAdapter_
-
-#include <memory>
-#include "qpid/Sasl.h"
-#include "qpid/broker/SaslAuthenticator.h"
-#include "qpid/framing/amqp_types.h"
-#include "qpid/framing/AMQFrame.h"
-#include "qpid/framing/AMQP_AllOperations.h"
-#include "qpid/framing/AMQP_AllProxy.h"
-#include "qpid/framing/enum.h"
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/ProtocolInitiation.h"
-#include "qpid/framing/ProtocolVersion.h"
-#include "qpid/Exception.h"
-#include "qpid/broker/AclModule.h"
-#include "qpid/sys/SecurityLayer.h"
-
-
-namespace qpid {
-
-namespace sys {
-struct SecuritySettings;
-}
-
-
-namespace broker {
-
-class Connection;
-class SecureConnection;
-
-class ConnectionHandler : public framing::FrameHandler
-{
- struct Handler : public framing::AMQP_AllOperations::ConnectionHandler
- {
- framing::AMQP_AllProxy::Connection proxy;
- Connection& connection;
- bool serverMode;
- std::auto_ptr<SaslAuthenticator> authenticator;
- AclModule* acl;
- SecureConnection* secured;
- bool isOpen;
-
- Handler(Connection& connection, bool isClient, bool isShadow=false);
- ~Handler();
- void startOk(const qpid::framing::FieldTable& clientProperties,
- const std::string& mechanism, const std::string& response,
- const std::string& locale);
- void secureOk(const std::string& response);
- void tuneOk(uint16_t channelMax, uint16_t frameMax, uint16_t heartbeat);
- void heartbeat();
- void open(const std::string& virtualHost,
- const framing::Array& capabilities, bool insist);
- void close(uint16_t replyCode, const std::string& replyText);
- void closeOk();
-
- void start(const qpid::framing::FieldTable& serverProperties,
- const framing::Array& mechanisms,
- const framing::Array& locales);
-
- void secure(const std::string& challenge);
-
- void tune(uint16_t channelMax,
- uint16_t frameMax,
- uint16_t heartbeatMin,
- uint16_t heartbeatMax);
-
- void openOk(const framing::Array& knownHosts);
-
- void redirect(const std::string& host, const framing::Array& knownHosts);
-
- std::auto_ptr<Sasl> sasl;
- typedef boost::function<const qpid::sys::SecuritySettings*()> GetSecuritySettings;
- std::string saslUserId;
- uint16_t maxFrameSize;
- };
- std::auto_ptr<Handler> handler;
-
-
- public:
- ConnectionHandler(Connection& connection, bool isClient, bool isShadow=false );
- void close(framing::connection::CloseCode code, const std::string& text);
- void heartbeat();
- void handle(framing::AMQFrame& frame);
- void setSecureConnection(SecureConnection* secured);
- bool isOpen() { return handler->isOpen; }
-};
-
-
-}}
-
-#endif
diff --git a/cpp/src/qpid/broker/ConnectionState.h b/cpp/src/qpid/broker/ConnectionState.h
deleted file mode 100644
index 9c31a931d8..0000000000
--- a/cpp/src/qpid/broker/ConnectionState.h
+++ /dev/null
@@ -1,117 +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.
- *
- */
-#ifndef _ConnectionState_
-#define _ConnectionState_
-
-#include <vector>
-
-#include "qpid/sys/AggregateOutput.h"
-#include "qpid/sys/ConnectionOutputHandlerPtr.h"
-#include "qpid/framing/ProtocolVersion.h"
-#include "qpid/management/Manageable.h"
-#include "qpid/Url.h"
-#include "qpid/broker/Broker.h"
-
-namespace qpid {
-namespace broker {
-
-class ConnectionState : public ConnectionToken, public management::Manageable
-{
- protected:
- sys::ConnectionOutputHandlerPtr out;
-
- public:
- ConnectionState(qpid::sys::ConnectionOutputHandler* o, Broker& b) :
- out(o),
- broker(b),
- outputTasks(out),
- framemax(65535),
- heartbeat(0),
- heartbeatmax(120),
- federationLink(true),
- clientSupportsThrottling(false),
- clusterOrderOut(0)
- {}
-
- virtual ~ConnectionState () {}
-
- uint32_t getFrameMax() const { return framemax; }
- uint16_t getHeartbeat() const { return heartbeat; }
- uint16_t getHeartbeatMax() const { return heartbeatmax; }
-
- void setFrameMax(uint32_t fm) { framemax = std::max(fm, (uint32_t) 4096); }
- void setHeartbeat(uint16_t hb) { heartbeat = hb; }
- void setHeartbeatMax(uint16_t hbm) { heartbeatmax = hbm; }
-
- virtual void setUserId(const std::string& uid) { userId = uid; }
- const std::string& getUserId() const { return userId; }
-
- void setUrl(const std::string& _url) { url = _url; }
- const std::string& getUrl() const { return url; }
-
- void setFederationLink(bool b) { federationLink = b; }
- bool isFederationLink() const { return federationLink; }
- void setFederationPeerTag(const std::string& tag) { federationPeerTag = std::string(tag); }
- const std::string& getFederationPeerTag() const { return federationPeerTag; }
- std::vector<Url>& getKnownHosts() { return knownHosts; }
-
- void setClientThrottling(bool set=true) { clientSupportsThrottling = set; }
- bool getClientThrottling() const { return clientSupportsThrottling; }
-
- Broker& getBroker() { return broker; }
-
- Broker& broker;
-
- //contained output tasks
- sys::AggregateOutput outputTasks;
-
- sys::ConnectionOutputHandler& getOutput() { return out; }
- framing::ProtocolVersion getVersion() const { return version; }
- void setOutputHandler(qpid::sys::ConnectionOutputHandler* o) { out.set(o); }
-
- /**
- * If the broker is part of a cluster, this is a handler provided
- * by cluster code. It ensures consistent ordering of commands
- * that are sent based on criteria that are not predictably
- * ordered cluster-wide, e.g. a timer firing.
- */
- framing::FrameHandler* getClusterOrderOutput() { return clusterOrderOut; }
- void setClusterOrderOutput(framing::FrameHandler& fh) { clusterOrderOut = &fh; }
-
- virtual void requestIOProcessing (boost::function0<void>) = 0;
-
- protected:
- framing::ProtocolVersion version;
- uint32_t framemax;
- uint16_t heartbeat;
- uint16_t heartbeatmax;
- std::string userId;
- std::string url;
- bool federationLink;
- std::string federationPeerTag;
- std::vector<Url> knownHosts;
- bool clientSupportsThrottling;
- framing::FrameHandler* clusterOrderOut;
-};
-
-}}
-
-#endif
diff --git a/cpp/src/qpid/broker/ConnectionToken.h b/cpp/src/qpid/broker/ConnectionToken.h
deleted file mode 100644
index 9b40383c80..0000000000
--- a/cpp/src/qpid/broker/ConnectionToken.h
+++ /dev/null
@@ -1,40 +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.
- *
- */
-#ifndef _ConnectionToken_
-#define _ConnectionToken_
-
-#include "qpid/broker/OwnershipToken.h"
-namespace qpid {
- namespace broker {
- /**
- * An empty interface allowing opaque implementations of some
- * form of token to identify a connection.
- */
- class ConnectionToken : public OwnershipToken {
- public:
- virtual bool isLocal(const ConnectionToken* t) const { return this == t; }
- virtual ~ConnectionToken(){}
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/Consumer.h b/cpp/src/qpid/broker/Consumer.h
deleted file mode 100644
index 317338a8ad..0000000000
--- a/cpp/src/qpid/broker/Consumer.h
+++ /dev/null
@@ -1,58 +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.
- *
- */
-#ifndef _Consumer_
-#define _Consumer_
-
-#include "qpid/broker/Message.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/broker/OwnershipToken.h"
-
-namespace qpid {
-namespace broker {
-
-class Queue;
-class QueueListeners;
-
-class Consumer {
- const bool acquires;
- // inListeners allows QueueListeners to efficiently track if this instance is registered
- // for notifications without having to search its containers
- bool inListeners;
- public:
- typedef boost::shared_ptr<Consumer> shared_ptr;
-
- framing::SequenceNumber position;
-
- Consumer(bool preAcquires = true) : acquires(preAcquires), inListeners(false) {}
- bool preAcquires() const { return acquires; }
- virtual bool deliver(QueuedMessage& msg) = 0;
- virtual void notify() = 0;
- virtual bool filter(boost::intrusive_ptr<Message>) { return true; }
- virtual bool accept(boost::intrusive_ptr<Message>) { return true; }
- virtual OwnershipToken* getSession() = 0;
- virtual ~Consumer(){}
- friend class QueueListeners;
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/Daemon.cpp b/cpp/src/qpid/broker/Daemon.cpp
deleted file mode 100644
index b30e5f18cb..0000000000
--- a/cpp/src/qpid/broker/Daemon.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/*
- * TODO: Note this is really a Posix specific implementation and so should be
- * refactored together with windows/QpiddBroker into a more coherent daemon driver/
- * platform specific split
- */
-#include "qpid/broker/Daemon.h"
-#include "qpid/log/Statement.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/posix/PidFile.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace qpid {
-namespace broker {
-
-using namespace std;
-using qpid::sys::PidFile;
-
-Daemon::Daemon(std::string _pidDir) : pidDir(_pidDir) {
- struct stat s;
- pid = -1;
- pipeFds[0] = pipeFds[1] = -1;
-
- if (::stat(pidDir.c_str(), &s)) {
- if (errno == ENOENT) {
- if (::mkdir(pidDir.c_str(), 0755))
- throw Exception ("Can't create PID directory: " + pidDir);
- }
- else
- throw Exception ("PID directory not found: " + pidDir);
- }
-}
-
-string Daemon::pidFile(string pidDir, uint16_t port) {
- ostringstream path;
- path << pidDir << "/qpidd." << port << ".pid";
- return path.str();
-}
-
-/*
- * Rewritten using low-level IO, for compatibility
- * with earlier Boost versions, i.e. 103200.
- */
-void Daemon::fork()
-{
- if(::pipe(pipeFds) < 0) throw ErrnoException("Can't create pipe");
- if ((pid = ::fork()) < 0) throw ErrnoException("Daemon fork failed");
- if (pid == 0) { // Child
- try {
- QPID_LOG(debug, "Forked daemon child process");
-
- // File descriptors
- if(::close(pipeFds[0])<0) throw ErrnoException("Cannot close read pipe");
- if(::close(0)<0) throw ErrnoException("Cannot close stdin");
- if(::close(1)<0) throw ErrnoException("Cannot close stdout");
- if(::close(2)<0) throw ErrnoException("Cannot close stderr");
- int fd=::open("/dev/null",O_RDWR); // stdin
- if(fd != 0) throw ErrnoException("Cannot re-open stdin");
- if(::dup(fd)<0) throw ErrnoException("Cannot re-open stdout");
- if(::dup(fd)<0) throw ErrnoException("Cannot re-open stderror");
-
- // Misc
- if(setsid()<0) throw ErrnoException("Cannot set session ID");
- if(chdir(pidDir.c_str()) < 0) throw ErrnoException("Cannot change directory to "+pidDir);
- umask(027);
-
- // Child behavior
- child();
- }
- catch (const exception& e) {
- QPID_LOG(critical, "Unexpected error: " << e.what());
- uint16_t port = 0;
- int unused_ret; //Supress warning about ignoring return value.
- unused_ret = write(pipeFds[1], &port, sizeof(uint16_t));
-
- std::string pipeFailureMessage = e.what();
- unused_ret = write ( pipeFds[1],
- pipeFailureMessage.c_str(),
- strlen(pipeFailureMessage.c_str())
- );
- }
- }
- else { // Parent
- close(pipeFds[1]); // Write side.
- parent();
- }
-}
-
-Daemon::~Daemon() {
- if (!lockFile.empty())
- unlink(lockFile.c_str());
-}
-
-uint16_t Daemon::wait(int timeout) { // parent waits for child.
- try {
- errno = 0;
- struct timeval tv;
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- /*
- * Rewritten using low-level IO, for compatibility
- * with earlier Boost versions, i.e. 103200.
- */
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(pipeFds[0], &fds);
- int n=select(FD_SETSIZE, &fds, 0, 0, &tv);
- if(n==0) throw Exception("Timed out waiting for daemon (If store recovery is in progress, use longer wait time)");
- if(n<0) throw ErrnoException("Error waiting for daemon");
- uint16_t port = 0;
- /*
- * Read the child's port number from the pipe.
- */
- int desired_read = sizeof(uint16_t);
- if ( desired_read > ::read(pipeFds[0], & port, desired_read) )
- throw Exception("Cannot read from child process.");
-
- /*
- * If the port number is 0, the child has put an error message
- * on the pipe. Get it and throw it.
- */
- if ( 0 == port ) {
- // Skip whitespace
- char c = ' ';
- while ( isspace(c) ) {
- if ( 1 > ::read(pipeFds[0], &c, 1) )
- throw Exception("Child port == 0, and no error message on pipe.");
- }
-
- // Get Message
- string errmsg;
- do {
- errmsg += c;
- } while (::read(pipeFds[0], &c, 1));
- throw Exception("Daemon startup failed"+
- (errmsg.empty() ? string(".") : ": " + errmsg));
- }
- return port;
- }
- catch (const std::exception& e) {
- // Print directly to cerr. The caller will catch and log the
- // exception, but in the case of a daemon parent process we
- // also need to be sure the error goes to stderr. A
- // dameon's logging configuration normally does not log to
- // stderr.
- std::cerr << e.what() << endl;
- throw;
- }
-}
-
-
-/*
- * When the child is ready, it writes its pid to the
- * lockfile and its port number on the pipe back to
- * its parent process. This indicates that the
- * child has successfully daemonized. When the parent
- * hears the good news, it ill exit.
- */
-void Daemon::ready(uint16_t port) { // child
- lockFile = pidFile(pidDir, port);
- PidFile lf(lockFile, true);
-
- /*
- * Write the PID to the lockfile.
- */
- lf.writePid();
-
- /*
- * Write the port number to the parent.
- */
- int desired_write = sizeof(uint16_t);
- if ( desired_write > ::write(pipeFds[1], & port, desired_write) ) {
- throw Exception("Error writing to parent." );
- }
-
- QPID_LOG(debug, "Daemon ready on port: " << port);
-}
-
-/*
- * The parent process reads the child's pid
- * from the lockfile.
- */
-pid_t Daemon::getPid(string _pidDir, uint16_t port) {
- string name = pidFile(_pidDir, port);
- PidFile lf(name, false);
- pid_t pid = lf.readPid();
- if (kill(pid, 0) < 0 && errno != EPERM) {
- unlink(name.c_str());
- throw Exception("Removing stale lock file "+name);
- }
- return pid;
-}
-
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/Daemon.h b/cpp/src/qpid/broker/Daemon.h
deleted file mode 100644
index a9cd98bce2..0000000000
--- a/cpp/src/qpid/broker/Daemon.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef _broker_Daemon_h
-#define _broker_Daemon_h
-
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "qpid/sys/IntegerTypes.h"
-#include <boost/scoped_ptr.hpp>
-#include <boost/function.hpp>
-#include <boost/noncopyable.hpp>
-#include <string>
-
-
-namespace qpid {
-namespace broker {
-
-/**
- * Tools for forking and managing a daemon process.
- * NB: Only one Daemon instance is allowed in a process.
- */
-class Daemon : private boost::noncopyable
-{
- public:
- /** Check daemon is running on port, throw exception if not */
- static pid_t getPid(std::string pidDir, uint16_t port);
-
- Daemon(std::string pidDir);
-
- virtual ~Daemon();
-
- /**
- * Fork a daemon process.
- * Call parent() in the parent process, child() in the child.
- */
- void fork();
-
- protected:
-
- /** Called in parent process */
- virtual void parent() = 0;
-
- /** Called in child process */
- virtual void child() = 0;
-
- /** Call from parent(): wait for child to indicate it is ready.
- * @timeout in seconds to wait for response.
- * @return port passed by child to ready().
- */
- uint16_t wait(int timeout);
-
- /** Call from child(): Notify the parent we are ready and write the
- * PID file.
- *@param port returned by parent call to wait().
- */
- void ready(uint16_t port);
-
- private:
- static std::string pidFile(std::string pidDir, uint16_t port);
-
- pid_t pid;
- int pipeFds[2];
- int lockFileFd;
- std::string lockFile;
- std::string pidDir;
-};
-
-}} // namespace qpid::broker
-
-#endif /*!_broker_Daemon_h*/
diff --git a/cpp/src/qpid/broker/Deliverable.h b/cpp/src/qpid/broker/Deliverable.h
deleted file mode 100644
index ffb5a77bca..0000000000
--- a/cpp/src/qpid/broker/Deliverable.h
+++ /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.
- *
- */
-#ifndef _Deliverable_
-#define _Deliverable_
-
-#include "qpid/broker/Message.h"
-
-namespace qpid {
- namespace broker {
- class Deliverable{
- public:
- bool delivered;
- Deliverable() : delivered(false) {}
-
- virtual Message& getMessage() = 0;
-
- virtual void deliverTo(const boost::shared_ptr<Queue>& queue) = 0;
- virtual uint64_t contentSize() { return 0; }
- virtual ~Deliverable(){}
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DeliverableMessage.cpp b/cpp/src/qpid/broker/DeliverableMessage.cpp
deleted file mode 100644
index 3ebb12461c..0000000000
--- a/cpp/src/qpid/broker/DeliverableMessage.cpp
+++ /dev/null
@@ -1,45 +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.
- *
- */
-
-#include "qpid/broker/DeliverableMessage.h"
-#include "qpid/broker/Queue.h"
-
-using namespace qpid::broker;
-
-DeliverableMessage::DeliverableMessage(const boost::intrusive_ptr<Message>& _msg) : msg(_msg)
-{
-}
-
-void DeliverableMessage::deliverTo(const boost::shared_ptr<Queue>& queue)
-{
- queue->deliver(msg);
- delivered = true;
-}
-
-Message& DeliverableMessage::getMessage()
-{
- return *msg;
-}
-
-uint64_t DeliverableMessage::contentSize ()
-{
- return msg->contentSize ();
-}
diff --git a/cpp/src/qpid/broker/DeliverableMessage.h b/cpp/src/qpid/broker/DeliverableMessage.h
deleted file mode 100644
index c8d21001eb..0000000000
--- a/cpp/src/qpid/broker/DeliverableMessage.h
+++ /dev/null
@@ -1,45 +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.
- *
- */
-#ifndef _DeliverableMessage_
-#define _DeliverableMessage_
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Deliverable.h"
-#include "qpid/broker/Message.h"
-
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
- namespace broker {
- class QPID_BROKER_CLASS_EXTERN DeliverableMessage : public Deliverable{
- boost::intrusive_ptr<Message> msg;
- public:
- QPID_BROKER_EXTERN DeliverableMessage(const boost::intrusive_ptr<Message>& msg);
- QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
- QPID_BROKER_EXTERN Message& getMessage();
- QPID_BROKER_EXTERN uint64_t contentSize();
- virtual ~DeliverableMessage(){}
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DeliveryAdapter.h b/cpp/src/qpid/broker/DeliveryAdapter.h
deleted file mode 100644
index b0bec60890..0000000000
--- a/cpp/src/qpid/broker/DeliveryAdapter.h
+++ /dev/null
@@ -1,53 +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.
- *
- */
-#ifndef _DeliveryAdapter_
-#define _DeliveryAdapter_
-
-#include "qpid/broker/DeliveryId.h"
-#include "qpid/broker/Message.h"
-#include "qpid/framing/amqp_types.h"
-
-namespace qpid {
-namespace broker {
-
-class DeliveryRecord;
-
-/**
- * The intention behind this interface is to separate the generic
- * handling of some form of message delivery to clients that is
- * contained in the version independent Channel class from the
- * details required for a particular situation or
- * version. i.e. where the existing adapters allow (through
- * supporting the generated interface for a version of the
- * protocol) inputs of a channel to be adapted to the version
- * independent part, this does the same for the outputs.
- */
-class DeliveryAdapter
-{
- public:
- virtual void deliver(DeliveryRecord&, bool sync) = 0;
- virtual ~DeliveryAdapter(){}
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DeliveryId.h b/cpp/src/qpid/broker/DeliveryId.h
deleted file mode 100644
index 05b19f032e..0000000000
--- a/cpp/src/qpid/broker/DeliveryId.h
+++ /dev/null
@@ -1,35 +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.
- *
- */
-#ifndef _DeliveryId_
-#define _DeliveryId_
-
-#include "qpid/framing/SequenceNumber.h"
-#include "qpid/framing/SequenceNumberSet.h"
-
-namespace qpid {
-namespace broker {
-
- typedef framing::SequenceNumber DeliveryId;
- typedef framing::SequenceNumberSet DeliveryIds;
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DeliveryRecord.cpp b/cpp/src/qpid/broker/DeliveryRecord.cpp
deleted file mode 100644
index 58dcc6d7c7..0000000000
--- a/cpp/src/qpid/broker/DeliveryRecord.cpp
+++ /dev/null
@@ -1,196 +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.
- *
- */
-#include "qpid/broker/DeliveryRecord.h"
-#include "qpid/broker/DeliverableMessage.h"
-#include "qpid/broker/SemanticState.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/MessageTransferBody.h"
-
-using namespace qpid;
-using namespace qpid::broker;
-using std::string;
-
-DeliveryRecord::DeliveryRecord(const QueuedMessage& _msg,
- const Queue::shared_ptr& _queue,
- const std::string& _tag,
- bool _acquired,
- bool accepted,
- bool _windowing,
- uint32_t _credit) : msg(_msg),
- queue(_queue),
- tag(_tag),
- acquired(_acquired),
- acceptExpected(!accepted),
- cancelled(false),
- completed(false),
- ended(accepted && acquired),
- windowing(_windowing),
- credit(msg.payload ? msg.payload->getRequiredCredit() : _credit)
-{}
-
-bool DeliveryRecord::setEnded()
-{
- ended = true;
- //reset msg pointer, don't need to hold on to it anymore
- msg.payload = boost::intrusive_ptr<Message>();
- QPID_LOG(debug, "DeliveryRecord::setEnded() id=" << id);
- return isRedundant();
-}
-
-void DeliveryRecord::redeliver(SemanticState* const session) {
- if (!ended) {
- if(cancelled){
- //if subscription was cancelled, requeue it (waiting for
- //final confirmation for AMQP WG on this case)
- requeue();
- }else{
- msg.payload->redeliver();//mark as redelivered
- session->deliver(*this, false);
- }
- }
-}
-
-void DeliveryRecord::deliver(framing::FrameHandler& h, DeliveryId deliveryId, uint16_t framesize)
-{
- id = deliveryId;
- if (msg.payload->getRedelivered()){
- msg.payload->getProperties<framing::DeliveryProperties>()->setRedelivered(true);
- }
- msg.payload->adjustTtl();
-
- framing::AMQFrame method((framing::MessageTransferBody(framing::ProtocolVersion(), tag, acceptExpected ? 0 : 1, acquired ? 0 : 1)));
- method.setEof(false);
- h.handle(method);
- msg.payload->sendHeader(h, framesize);
- msg.payload->sendContent(*queue, h, framesize);
-}
-
-void DeliveryRecord::requeue() const
-{
- if (acquired && !ended) {
- msg.payload->redeliver();
- queue->requeue(msg);
- }
-}
-
-void DeliveryRecord::release(bool setRedelivered)
-{
- if (acquired && !ended) {
- if (setRedelivered) msg.payload->redeliver();
- queue->requeue(msg);
- acquired = false;
- setEnded();
- } else {
- QPID_LOG(debug, "Ignoring release for " << id << " acquired=" << acquired << ", ended =" << ended);
- }
-}
-
-void DeliveryRecord::complete() {
- completed = true;
-}
-
-bool DeliveryRecord::accept(TransactionContext* ctxt) {
- if (acquired && !ended) {
- queue->dequeue(ctxt, msg);
- setEnded();
- QPID_LOG(debug, "Accepted " << id);
- }
- return isRedundant();
-}
-
-void DeliveryRecord::dequeue(TransactionContext* ctxt) const{
- if (acquired && !ended) {
- queue->dequeue(ctxt, msg);
- }
-}
-
-void DeliveryRecord::committed() const{
- queue->dequeueCommitted(msg);
-}
-
-void DeliveryRecord::reject()
-{
- if (acquired && !ended) {
- Exchange::shared_ptr alternate = queue->getAlternateExchange();
- if (alternate) {
- DeliverableMessage delivery(msg.payload);
- alternate->routeWithAlternate(delivery);
- QPID_LOG(info, "Routed rejected message from " << queue->getName() << " to "
- << alternate->getName());
- } else {
- //just drop it
- QPID_LOG(info, "Dropping rejected message from " << queue->getName());
- }
- dequeue();
- setEnded();
- }
-}
-
-uint32_t DeliveryRecord::getCredit() const
-{
- return credit;
-}
-
-void DeliveryRecord::acquire(DeliveryIds& results) {
- if (queue->acquire(msg)) {
- acquired = true;
- results.push_back(id);
- if (!acceptExpected) {
- if (ended) { QPID_LOG(error, "Can't dequeue ended message"); }
- else { queue->dequeue(0, msg); setEnded(); }
- }
- } else {
- QPID_LOG(info, "Message already acquired " << id.getValue());
- }
-}
-
-void DeliveryRecord::cancel(const std::string& cancelledTag)
-{
- if (tag == cancelledTag)
- cancelled = true;
-}
-
-AckRange DeliveryRecord::findRange(DeliveryRecords& records, DeliveryId first, DeliveryId last)
-{
- DeliveryRecords::iterator start = lower_bound(records.begin(), records.end(), first);
- // Find end - position it just after the last record in range
- DeliveryRecords::iterator end = lower_bound(records.begin(), records.end(), last);
- if (end != records.end() && end->getId() == last) ++end;
- return AckRange(start, end);
-}
-
-
-namespace qpid {
-namespace broker {
-
-std::ostream& operator<<(std::ostream& out, const DeliveryRecord& r)
-{
- out << "{" << "id=" << r.id.getValue();
- out << ", tag=" << r.tag << "}";
- out << ", queue=" << r.queue->getName() << "}";
- return out;
-}
-
-
-}}
diff --git a/cpp/src/qpid/broker/DeliveryRecord.h b/cpp/src/qpid/broker/DeliveryRecord.h
deleted file mode 100644
index d388ba94be..0000000000
--- a/cpp/src/qpid/broker/DeliveryRecord.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#ifndef QPID_BROKER_DELIVERYRECORD_H
-#define QPID_BROKER_DELIVERYRECORD_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <algorithm>
-#include <deque>
-#include <vector>
-#include <ostream>
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/broker/DeliveryId.h"
-#include "qpid/broker/Message.h"
-
-namespace qpid {
-namespace broker {
-
-class TransactionContext;
-class SemanticState;
-struct AckRange;
-
-/**
- * Record of a delivery for which an ack is outstanding.
- */
-class DeliveryRecord
-{
- QueuedMessage msg;
- mutable boost::shared_ptr<Queue> queue;
- std::string tag;
- DeliveryId id;
- bool acquired : 1;
- bool acceptExpected : 1;
- bool cancelled : 1;
- bool completed : 1;
- bool ended : 1;
- bool windowing : 1;
-
- /**
- * Record required credit on construction as the pointer to the
- * message may be reset once we no longer need to deliver it
- * (e.g. when it is accepted), but we will still need to be able
- * to reallocate credit when it is completed (which could happen
- * after that).
- */
- uint32_t credit;
-
- public:
- QPID_BROKER_EXTERN DeliveryRecord(const QueuedMessage& msg,
- const boost::shared_ptr<Queue>& queue,
- const std::string& tag,
- bool acquired,
- bool accepted,
- bool windowing,
- uint32_t credit=0 // Only used if msg is empty.
- );
-
- bool coveredBy(const framing::SequenceSet* const range) const { return range->contains(id); }
-
- void dequeue(TransactionContext* ctxt = 0) const;
- void requeue() const;
- void release(bool setRedelivered);
- void reject();
- void cancel(const std::string& tag);
- void redeliver(SemanticState* const);
- void acquire(DeliveryIds& results);
- void complete();
- bool accept(TransactionContext* ctxt); // Returns isRedundant()
- bool setEnded(); // Returns isRedundant()
- void committed() const;
-
- bool isAcquired() const { return acquired; }
- bool isComplete() const { return completed; }
- bool isRedundant() const { return ended && (!windowing || completed); }
- bool isCancelled() const { return cancelled; }
- bool isAccepted() const { return !acceptExpected; }
- bool isEnded() const { return ended; }
- bool isWindowing() const { return windowing; }
-
- uint32_t getCredit() const;
- const std::string& getTag() const { return tag; }
-
- void deliver(framing::FrameHandler& h, DeliveryId deliveryId, uint16_t framesize);
- void setId(DeliveryId _id) { id = _id; }
-
- typedef std::deque<DeliveryRecord> DeliveryRecords;
- static AckRange findRange(DeliveryRecords& records, DeliveryId first, DeliveryId last);
- const QueuedMessage& getMessage() const { return msg; }
- framing::SequenceNumber getId() const { return id; }
- boost::shared_ptr<Queue> getQueue() const { return queue; }
-
- friend std::ostream& operator<<(std::ostream&, const DeliveryRecord&);
-};
-
-inline bool operator<(const DeliveryRecord& a, const DeliveryRecord& b) { return a.getId() < b.getId(); }
-inline bool operator<(const framing::SequenceNumber& a, const DeliveryRecord& b) { return a < b.getId(); }
-inline bool operator<(const DeliveryRecord& a, const framing::SequenceNumber& b) { return a.getId() < b; }
-
-struct AcquireFunctor
-{
- DeliveryIds& results;
-
- AcquireFunctor(DeliveryIds& _results) : results(_results) {}
-
- void operator()(DeliveryRecord& record)
- {
- record.acquire(results);
- }
-};
-
-typedef DeliveryRecord::DeliveryRecords DeliveryRecords;
-
-struct AckRange
-{
- DeliveryRecords::iterator start;
- DeliveryRecords::iterator end;
- AckRange(DeliveryRecords::iterator _start, DeliveryRecords::iterator _end) : start(_start), end(_end) {}
-};
-
-}
-}
-
-
-#endif /*!QPID_BROKER_DELIVERYRECORD_H*/
diff --git a/cpp/src/qpid/broker/DirectExchange.cpp b/cpp/src/qpid/broker/DirectExchange.cpp
deleted file mode 100644
index 060f80f60d..0000000000
--- a/cpp/src/qpid/broker/DirectExchange.cpp
+++ /dev/null
@@ -1,194 +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.
- *
- */
-
-#include "qpid/log/Statement.h"
-#include "qpid/broker/FedOps.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/DirectExchange.h"
-#include <iostream>
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-using namespace qpid::sys;
-using qpid::management::Manageable;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace
-{
- const std::string qpidExclusiveBinding("qpid.exclusive-binding");
-}
-
-DirectExchange::DirectExchange(const string& _name, Manageable* _parent, Broker* b) : Exchange(_name, _parent, b)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type(typeName);
-}
-
-DirectExchange::DirectExchange(const string& _name, bool _durable,
- const FieldTable& _args, Manageable* _parent, Broker* b) :
- Exchange(_name, _durable, _args, _parent, b)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type(typeName);
-}
-
-bool DirectExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args)
-{
- string fedOp(fedOpBind);
- string fedTags;
- string fedOrigin;
- bool exclusiveBinding = false;
- if (args) {
- fedOp = args->getAsString(qpidFedOp);
- fedTags = args->getAsString(qpidFedTags);
- fedOrigin = args->getAsString(qpidFedOrigin);
- exclusiveBinding = args->get(qpidExclusiveBinding); // only direct exchanges take exclusive bindings
- }
-
- bool propagate = false;
-
- if (args == 0 || fedOp.empty() || fedOp == fedOpBind) {
- Mutex::ScopedLock l(lock);
- Binding::shared_ptr b(new Binding(routingKey, queue, this, FieldTable(), fedOrigin));
- BoundKey& bk = bindings[routingKey];
- if (exclusiveBinding) bk.queues.clear();
-
- QPID_LOG(debug, "Bind key [" << routingKey << "] to queue " << queue->getName()
- << " (origin=" << fedOrigin << ")");
-
- if (bk.queues.add_unless(b, MatchQueue(queue))) {
- b->startManagement();
- propagate = bk.fedBinding.addOrigin(queue->getName(), fedOrigin);
- if (mgmtExchange != 0) {
- mgmtExchange->inc_bindingCount();
- }
- } else {
- // queue already present - still need to track fedOrigin
- bk.fedBinding.addOrigin(queue->getName(), fedOrigin);
- return false;
- }
- } else if (fedOp == fedOpUnbind) {
- Mutex::ScopedLock l(lock);
- BoundKey& bk = bindings[routingKey];
-
- QPID_LOG(debug, "Bind - fedOpUnbind key [" << routingKey << "] queue " << queue->getName()
- << " (origin=" << fedOrigin << ")" << " (count=" << bk.fedBinding.count() << ")");
-
- propagate = bk.fedBinding.delOrigin(queue->getName(), fedOrigin);
- if (bk.fedBinding.countFedBindings(queue->getName()) == 0)
- unbind(queue, routingKey, args);
-
- } else if (fedOp == fedOpReorigin) {
- /** gather up all the keys that need rebinding in a local vector
- * while holding the lock. Then propagate once the lock is
- * released
- */
- std::vector<std::string> keys2prop;
- {
- Mutex::ScopedLock l(lock);
- for (Bindings::iterator iter = bindings.begin();
- iter != bindings.end(); iter++) {
- const BoundKey& bk = iter->second;
- if (bk.fedBinding.hasLocal()) {
- keys2prop.push_back(iter->first);
- }
- }
- } /* lock dropped */
- for (std::vector<std::string>::const_iterator key = keys2prop.begin();
- key != keys2prop.end(); key++) {
- propagateFedOp( *key, string(), fedOpBind, string());
- }
- }
-
- routeIVE();
- if (propagate)
- propagateFedOp(routingKey, fedTags, fedOp, fedOrigin);
- return true;
-}
-
-bool DirectExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args)
-{
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- bool propagate = false;
-
- QPID_LOG(debug, "Unbinding key [" << routingKey << "] from queue " << queue->getName()
- << " on exchange " << getName() << " origin=" << fedOrigin << ")" );
- {
- Mutex::ScopedLock l(lock);
- BoundKey& bk = bindings[routingKey];
- if (bk.queues.remove_if(MatchQueue(queue))) {
- propagate = bk.fedBinding.delOrigin(queue->getName(), fedOrigin);
- if (mgmtExchange != 0) {
- mgmtExchange->dec_bindingCount();
- }
- } else {
- return false;
- }
- }
-
- // If I delete my local binding, propagate this unbind to any upstream brokers
- if (propagate)
- propagateFedOp(routingKey, string(), fedOpUnbind, string());
- return true;
-}
-
-void DirectExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/)
-{
- PreRoute pr(msg, this);
- ConstBindingList b;
- {
- Mutex::ScopedLock l(lock);
- b = bindings[routingKey].queues.snapshot();
- }
- doRoute(msg, b);
-}
-
-
-bool DirectExchange::isBound(Queue::shared_ptr queue, const string* const routingKey, const FieldTable* const)
-{
- Mutex::ScopedLock l(lock);
- if (routingKey) {
- Bindings::iterator i = bindings.find(*routingKey);
-
- if (i == bindings.end())
- return false;
- if (!queue)
- return true;
-
- Queues::ConstPtr p = i->second.queues.snapshot();
- return p && std::find_if(p->begin(), p->end(), MatchQueue(queue)) != p->end();
- } else if (!queue) {
- //if no queue or routing key is specified, just report whether any bindings exist
- return bindings.size() > 0;
- } else {
- for (Bindings::iterator i = bindings.begin(); i != bindings.end(); i++) {
- Queues::ConstPtr p = i->second.queues.snapshot();
- if (p && std::find_if(p->begin(), p->end(), MatchQueue(queue)) != p->end()) return true;
- }
- return false;
- }
-
- return false;
-}
-
-DirectExchange::~DirectExchange() {}
-
-const std::string DirectExchange::typeName("direct");
diff --git a/cpp/src/qpid/broker/DirectExchange.h b/cpp/src/qpid/broker/DirectExchange.h
deleted file mode 100644
index a6f9cf91af..0000000000
--- a/cpp/src/qpid/broker/DirectExchange.h
+++ /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.
- *
- */
-#ifndef _DirectExchange_
-#define _DirectExchange_
-
-#include <map>
-#include <vector>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/CopyOnWriteArray.h"
-#include "qpid/sys/Mutex.h"
-
-namespace qpid {
-namespace broker {
-class DirectExchange : public virtual Exchange {
- typedef qpid::sys::CopyOnWriteArray<Binding::shared_ptr> Queues;
- struct BoundKey {
- Queues queues;
- FedBinding fedBinding;
- };
- typedef std::map<std::string, BoundKey> Bindings;
- Bindings bindings;
- qpid::sys::Mutex lock;
-
-public:
- static const std::string typeName;
-
- QPID_BROKER_EXTERN DirectExchange(const std::string& name,
- management::Manageable* parent = 0, Broker* broker = 0);
- QPID_BROKER_EXTERN DirectExchange(const std::string& _name,
- bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0, Broker* broker = 0);
-
- virtual std::string getType() const { return typeName; }
-
- QPID_BROKER_EXTERN virtual bool bind(boost::shared_ptr<Queue> queue,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
- virtual bool unbind(boost::shared_ptr<Queue> queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
- QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
- QPID_BROKER_EXTERN virtual bool isBound(boost::shared_ptr<Queue> queue,
- const std::string* const routingKey,
- const qpid::framing::FieldTable* const args);
-
- QPID_BROKER_EXTERN virtual ~DirectExchange();
-
- virtual bool supportsDynamicBinding() { return true; }
-};
-
-}}
-
-#endif
diff --git a/cpp/src/qpid/broker/DtxAck.cpp b/cpp/src/qpid/broker/DtxAck.cpp
deleted file mode 100644
index bca3f90bbe..0000000000
--- a/cpp/src/qpid/broker/DtxAck.cpp
+++ /dev/null
@@ -1,73 +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.
- *
- */
-#include "qpid/broker/DtxAck.h"
-#include "qpid/log/Statement.h"
-
-using std::bind1st;
-using std::bind2nd;
-using std::mem_fun_ref;
-using namespace qpid::broker;
-
-DtxAck::DtxAck(const qpid::framing::SequenceSet& acked, DeliveryRecords& unacked)
-{
- remove_copy_if(unacked.begin(), unacked.end(), inserter(pending, pending.end()),
- not1(bind2nd(mem_fun_ref(&DeliveryRecord::coveredBy), &acked)));
-}
-
-bool DtxAck::prepare(TransactionContext* ctxt) throw()
-{
- try{
- //record dequeue in the store
- for (DeliveryRecords::iterator i = pending.begin(); i != pending.end(); i++) {
- i->dequeue(ctxt);
- }
- return true;
- }catch(...){
- QPID_LOG(error, "Failed to prepare");
- return false;
- }
-}
-
-void DtxAck::commit() throw()
-{
- try {
- for_each(pending.begin(), pending.end(), mem_fun_ref(&DeliveryRecord::committed));
- pending.clear();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to commit: " << e.what());
- } catch(...) {
- QPID_LOG(error, "Failed to commit (unknown error)");
- }
-
-}
-
-void DtxAck::rollback() throw()
-{
- try {
- for_each(pending.begin(), pending.end(), mem_fun_ref(&DeliveryRecord::requeue));
- pending.clear();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to complete rollback: " << e.what());
- } catch(...) {
- QPID_LOG(error, "Failed to complete rollback (unknown error)");
- }
-
-}
diff --git a/cpp/src/qpid/broker/DtxAck.h b/cpp/src/qpid/broker/DtxAck.h
deleted file mode 100644
index 166147e58d..0000000000
--- a/cpp/src/qpid/broker/DtxAck.h
+++ /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.
- *
- */
-#ifndef _DtxAck_
-#define _DtxAck_
-
-#include <algorithm>
-#include <functional>
-#include <list>
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/broker/DeliveryRecord.h"
-#include "qpid/broker/TxOp.h"
-
-namespace qpid {
- namespace broker {
- class DtxAck : public TxOp{
- DeliveryRecords pending;
-
- public:
- DtxAck(const framing::SequenceSet& acked, DeliveryRecords& unacked);
- virtual bool prepare(TransactionContext* ctxt) throw();
- virtual void commit() throw();
- virtual void rollback() throw();
- virtual ~DtxAck(){}
- virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DtxBuffer.cpp b/cpp/src/qpid/broker/DtxBuffer.cpp
deleted file mode 100644
index f1b8169cf7..0000000000
--- a/cpp/src/qpid/broker/DtxBuffer.cpp
+++ /dev/null
@@ -1,83 +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.
- *
- */
-#include "qpid/broker/DtxBuffer.h"
-
-using namespace qpid::broker;
-using qpid::sys::Mutex;
-
-DtxBuffer::DtxBuffer(const std::string& _xid)
- : xid(_xid), ended(false), suspended(false), failed(false), expired(false) {}
-
-DtxBuffer::~DtxBuffer() {}
-
-void DtxBuffer::markEnded()
-{
- Mutex::ScopedLock locker(lock);
- ended = true;
-}
-
-bool DtxBuffer::isEnded()
-{
- Mutex::ScopedLock locker(lock);
- return ended;
-}
-
-void DtxBuffer::setSuspended(bool isSuspended)
-{
- suspended = isSuspended;
-}
-
-bool DtxBuffer::isSuspended()
-{
- return suspended;
-}
-
-void DtxBuffer::fail()
-{
- Mutex::ScopedLock locker(lock);
- rollback();
- failed = true;
- ended = true;
-}
-
-bool DtxBuffer::isRollbackOnly()
-{
- Mutex::ScopedLock locker(lock);
- return failed;
-}
-
-const std::string& DtxBuffer::getXid()
-{
- return xid;
-}
-
-void DtxBuffer::timedout()
-{
- Mutex::ScopedLock locker(lock);
- expired = true;
- fail();
-}
-
-bool DtxBuffer::isExpired()
-{
- Mutex::ScopedLock locker(lock);
- return expired;
-}
diff --git a/cpp/src/qpid/broker/DtxBuffer.h b/cpp/src/qpid/broker/DtxBuffer.h
deleted file mode 100644
index 1511cb032f..0000000000
--- a/cpp/src/qpid/broker/DtxBuffer.h
+++ /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.
- *
- */
-#ifndef _DtxBuffer_
-#define _DtxBuffer_
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/TxBuffer.h"
-#include "qpid/sys/Mutex.h"
-
-namespace qpid {
- namespace broker {
- class DtxBuffer : public TxBuffer{
- sys::Mutex lock;
- const std::string xid;
- bool ended;
- bool suspended;
- bool failed;
- bool expired;
-
- public:
- typedef boost::shared_ptr<DtxBuffer> shared_ptr;
-
- QPID_BROKER_EXTERN DtxBuffer(const std::string& xid = "");
- QPID_BROKER_EXTERN ~DtxBuffer();
- QPID_BROKER_EXTERN void markEnded();
- bool isEnded();
- void setSuspended(bool suspended);
- bool isSuspended();
- void fail();
- bool isRollbackOnly();
- void timedout();
- bool isExpired();
- const std::string& getXid();
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DtxManager.cpp b/cpp/src/qpid/broker/DtxManager.cpp
deleted file mode 100644
index 3caa41c3f4..0000000000
--- a/cpp/src/qpid/broker/DtxManager.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/DtxManager.h"
-#include "qpid/broker/DtxTimeout.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/Timer.h"
-#include "qpid/ptr_map.h"
-
-#include <boost/format.hpp>
-#include <iostream>
-
-using boost::intrusive_ptr;
-using qpid::sys::Mutex;
-using qpid::ptr_map_ptr;
-using namespace qpid::broker;
-using namespace qpid::framing;
-
-DtxManager::DtxManager(qpid::sys::Timer& t) : store(0), timer(t) {}
-
-DtxManager::~DtxManager() {}
-
-void DtxManager::start(const std::string& xid, DtxBuffer::shared_ptr ops)
-{
- createWork(xid)->add(ops);
-}
-
-void DtxManager::join(const std::string& xid, DtxBuffer::shared_ptr ops)
-{
- getWork(xid)->add(ops);
-}
-
-void DtxManager::recover(const std::string& xid, std::auto_ptr<TPCTransactionContext> txn, DtxBuffer::shared_ptr ops)
-{
- createWork(xid)->recover(txn, ops);
-}
-
-bool DtxManager::prepare(const std::string& xid)
-{
- QPID_LOG(debug, "preparing: " << xid);
- try {
- return getWork(xid)->prepare();
- } catch (DtxTimeoutException& e) {
- remove(xid);
- throw e;
- }
-}
-
-bool DtxManager::commit(const std::string& xid, bool onePhase)
-{
- QPID_LOG(debug, "committing: " << xid);
- try {
- bool result = getWork(xid)->commit(onePhase);
- remove(xid);
- return result;
- } catch (DtxTimeoutException& e) {
- remove(xid);
- throw e;
- }
-}
-
-void DtxManager::rollback(const std::string& xid)
-{
- QPID_LOG(debug, "rolling back: " << xid);
- try {
- getWork(xid)->rollback();
- remove(xid);
- } catch (DtxTimeoutException& e) {
- remove(xid);
- throw e;
- }
-}
-
-DtxWorkRecord* DtxManager::getWork(const std::string& xid)
-{
- Mutex::ScopedLock locker(lock);
- WorkMap::iterator i = work.find(xid);
- if (i == work.end()) {
- throw NotFoundException(QPID_MSG("Unrecognised xid " << xid));
- }
- return ptr_map_ptr(i);
-}
-
-void DtxManager::remove(const std::string& xid)
-{
- Mutex::ScopedLock locker(lock);
- WorkMap::iterator i = work.find(xid);
- if (i == work.end()) {
- throw NotFoundException(QPID_MSG("Unrecognised xid " << xid));
- } else {
- work.erase(i);
- }
-}
-
-DtxWorkRecord* DtxManager::createWork(std::string xid)
-{
- Mutex::ScopedLock locker(lock);
- WorkMap::iterator i = work.find(xid);
- if (i != work.end()) {
- throw NotAllowedException(QPID_MSG("Xid " << xid << " is already known (use 'join' to add work to an existing xid)"));
- } else {
- return ptr_map_ptr(work.insert(xid, new DtxWorkRecord(xid, store)).first);
- }
-}
-
-void DtxManager::setTimeout(const std::string& xid, uint32_t secs)
-{
- DtxWorkRecord* record = getWork(xid);
- intrusive_ptr<DtxTimeout> timeout = record->getTimeout();
- if (timeout.get()) {
- if (timeout->timeout == secs) return;//no need to do anything further if timeout hasn't changed
- timeout->cancel();
- }
- timeout = intrusive_ptr<DtxTimeout>(new DtxTimeout(secs, *this, xid));
- record->setTimeout(timeout);
- timer.add(timeout);
-}
-
-uint32_t DtxManager::getTimeout(const std::string& xid)
-{
- intrusive_ptr<DtxTimeout> timeout = getWork(xid)->getTimeout();
- return !timeout ? 0 : timeout->timeout;
-}
-
-void DtxManager::timedout(const std::string& xid)
-{
- Mutex::ScopedLock locker(lock);
- WorkMap::iterator i = work.find(xid);
- if (i == work.end()) {
- QPID_LOG(warning, "Transaction timeout failed: no record for xid");
- } else {
- ptr_map_ptr(i)->timedout();
- //TODO: do we want to have a timed task to cleanup, or can we rely on an explicit completion?
- //timer.add(intrusive_ptr<TimerTask>(new DtxCleanup(60*30/*30 mins*/, *this, xid)));
- }
-}
-
-DtxManager::DtxCleanup::DtxCleanup(uint32_t _timeout, DtxManager& _mgr, const std::string& _xid)
- : TimerTask(qpid::sys::Duration(_timeout * qpid::sys::TIME_SEC),"DtxCleanup"), mgr(_mgr), xid(_xid) {}
-
-void DtxManager::DtxCleanup::fire()
-{
- try {
- mgr.remove(xid);
- } catch (ConnectionException& /*e*/) {
- //assume it was explicitly cleaned up after a call to prepare, commit or rollback
- }
-}
-
-void DtxManager::setStore (TransactionalStore* _store)
-{
- store = _store;
-}
diff --git a/cpp/src/qpid/broker/DtxManager.h b/cpp/src/qpid/broker/DtxManager.h
deleted file mode 100644
index 680b62eeb2..0000000000
--- a/cpp/src/qpid/broker/DtxManager.h
+++ /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.
- *
- */
-#ifndef _DtxManager_
-#define _DtxManager_
-
-#include <boost/ptr_container/ptr_map.hpp>
-#include "qpid/broker/DtxBuffer.h"
-#include "qpid/broker/DtxWorkRecord.h"
-#include "qpid/broker/TransactionalStore.h"
-#include "qpid/framing/amqp_types.h"
-#include "qpid/sys/Timer.h"
-#include "qpid/sys/Mutex.h"
-
-namespace qpid {
-namespace broker {
-
-class DtxManager{
- typedef boost::ptr_map<std::string, DtxWorkRecord> WorkMap;
-
- struct DtxCleanup : public sys::TimerTask
- {
- DtxManager& mgr;
- const std::string& xid;
-
- DtxCleanup(uint32_t timeout, DtxManager& mgr, const std::string& xid);
- void fire();
- };
-
- WorkMap work;
- TransactionalStore* store;
- qpid::sys::Mutex lock;
- qpid::sys::Timer& timer;
-
- void remove(const std::string& xid);
- DtxWorkRecord* getWork(const std::string& xid);
- DtxWorkRecord* createWork(std::string xid);
-
-public:
- DtxManager(qpid::sys::Timer&);
- ~DtxManager();
- void start(const std::string& xid, DtxBuffer::shared_ptr work);
- void join(const std::string& xid, DtxBuffer::shared_ptr work);
- void recover(const std::string& xid, std::auto_ptr<TPCTransactionContext> txn, DtxBuffer::shared_ptr work);
- bool prepare(const std::string& xid);
- bool commit(const std::string& xid, bool onePhase);
- void rollback(const std::string& xid);
- void setTimeout(const std::string& xid, uint32_t secs);
- uint32_t getTimeout(const std::string& xid);
- void timedout(const std::string& xid);
- void setStore(TransactionalStore* store);
-};
-
-}
-}
-
-#endif
diff --git a/cpp/src/qpid/broker/DtxTimeout.cpp b/cpp/src/qpid/broker/DtxTimeout.cpp
deleted file mode 100644
index c4c52ec40a..0000000000
--- a/cpp/src/qpid/broker/DtxTimeout.cpp
+++ /dev/null
@@ -1,35 +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.
- *
- */
-#include "qpid/broker/DtxTimeout.h"
-#include "qpid/broker/DtxManager.h"
-#include "qpid/sys/Time.h"
-
-using namespace qpid::broker;
-
-DtxTimeout::DtxTimeout(uint32_t _timeout, DtxManager& _mgr, const std::string& _xid)
- : TimerTask(qpid::sys::Duration(_timeout * qpid::sys::TIME_SEC),"DtxTimeout"), timeout(_timeout), mgr(_mgr), xid(_xid)
-{
-}
-
-void DtxTimeout::fire()
-{
- mgr.timedout(xid);
-}
diff --git a/cpp/src/qpid/broker/DtxTimeout.h b/cpp/src/qpid/broker/DtxTimeout.h
deleted file mode 100644
index 680a210e4f..0000000000
--- a/cpp/src/qpid/broker/DtxTimeout.h
+++ /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.
- *
- */
-#ifndef _DtxTimeout_
-#define _DtxTimeout_
-
-#include "qpid/Exception.h"
-#include "qpid/sys/Timer.h"
-
-namespace qpid {
-namespace broker {
-
-class DtxManager;
-
-struct DtxTimeoutException : public Exception {};
-
-struct DtxTimeout : public sys::TimerTask
-{
- const uint32_t timeout;
- DtxManager& mgr;
- const std::string xid;
-
- DtxTimeout(uint32_t timeout, DtxManager& mgr, const std::string& xid);
- void fire();
-};
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/DtxWorkRecord.cpp b/cpp/src/qpid/broker/DtxWorkRecord.cpp
deleted file mode 100644
index 9f33e698db..0000000000
--- a/cpp/src/qpid/broker/DtxWorkRecord.cpp
+++ /dev/null
@@ -1,177 +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.
- *
- */
-#include "qpid/broker/DtxWorkRecord.h"
-#include "qpid/framing/reply_exceptions.h"
-#include <boost/format.hpp>
-#include <boost/mem_fn.hpp>
-using boost::mem_fn;
-using qpid::sys::Mutex;
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-
-DtxWorkRecord::DtxWorkRecord(const std::string& _xid, TransactionalStore* const _store) :
- xid(_xid), store(_store), completed(false), rolledback(false), prepared(false), expired(false) {}
-
-DtxWorkRecord::~DtxWorkRecord()
-{
- if (timeout.get()) {
- timeout->cancel();
- }
-}
-
-bool DtxWorkRecord::prepare()
-{
- Mutex::ScopedLock locker(lock);
- if (check()) {
- txn = store->begin(xid);
- if (prepare(txn.get())) {
- store->prepare(*txn);
- prepared = true;
- } else {
- abort();
- //TODO: this should probably be flagged as internal error
- }
- } else {
- //some part of the work has been marked rollback only
- abort();
- }
- return prepared;
-}
-
-bool DtxWorkRecord::prepare(TransactionContext* _txn)
-{
- bool succeeded(true);
- for (Work::iterator i = work.begin(); succeeded && i != work.end(); i++) {
- succeeded = (*i)->prepare(_txn);
- }
- return succeeded;
-}
-
-bool DtxWorkRecord::commit(bool onePhase)
-{
- Mutex::ScopedLock locker(lock);
- if (check()) {
- if (prepared) {
- //already prepared i.e. 2pc
- if (onePhase) {
- throw IllegalStateException(QPID_MSG("Branch with xid " << xid << " has been prepared, one-phase option not valid!"));
- }
-
- store->commit(*txn);
- txn.reset();
-
- std::for_each(work.begin(), work.end(), mem_fn(&TxBuffer::commit));
- return true;
- } else {
- //1pc commit optimisation, don't need a 2pc transaction context:
- if (!onePhase) {
- throw IllegalStateException(QPID_MSG("Branch with xid " << xid << " has not been prepared, one-phase option required!"));
- }
- std::auto_ptr<TransactionContext> localtxn = store->begin();
- if (prepare(localtxn.get())) {
- store->commit(*localtxn);
- std::for_each(work.begin(), work.end(), mem_fn(&TxBuffer::commit));
- return true;
- } else {
- store->abort(*localtxn);
- abort();
- //TODO: this should probably be flagged as internal error
- return false;
- }
- }
- } else {
- //some part of the work has been marked rollback only
- abort();
- return false;
- }
-}
-
-void DtxWorkRecord::rollback()
-{
- Mutex::ScopedLock locker(lock);
- check();
- abort();
-}
-
-void DtxWorkRecord::add(DtxBuffer::shared_ptr ops)
-{
- Mutex::ScopedLock locker(lock);
- if (expired) {
- throw DtxTimeoutException();
- }
- if (completed) {
- throw CommandInvalidException(QPID_MSG("Branch with xid " << xid << " has been completed!"));
- }
- work.push_back(ops);
-}
-
-bool DtxWorkRecord::check()
-{
- if (expired) {
- throw DtxTimeoutException();
- }
- if (!completed) {
- //iterate through all DtxBuffers and ensure they are all ended
- for (Work::iterator i = work.begin(); i != work.end(); i++) {
- if (!(*i)->isEnded()) {
- throw IllegalStateException(QPID_MSG("Branch with xid " << xid << " not completed!"));
- } else if ((*i)->isRollbackOnly()) {
- rolledback = true;
- }
- }
- completed = true;
- }
- return !rolledback;
-}
-
-void DtxWorkRecord::abort()
-{
- if (txn.get()) {
- store->abort(*txn);
- txn.reset();
- }
- std::for_each(work.begin(), work.end(), mem_fn(&TxBuffer::rollback));
-}
-
-void DtxWorkRecord::recover(std::auto_ptr<TPCTransactionContext> _txn, DtxBuffer::shared_ptr ops)
-{
- add(ops);
- txn = _txn;
- ops->markEnded();
- completed = true;
- prepared = true;
-}
-
-void DtxWorkRecord::timedout()
-{
- Mutex::ScopedLock locker(lock);
- expired = true;
- rolledback = true;
- if (!completed) {
- for (Work::iterator i = work.begin(); i != work.end(); i++) {
- if (!(*i)->isEnded()) {
- (*i)->timedout();
- }
- }
- }
- abort();
-}
diff --git a/cpp/src/qpid/broker/DtxWorkRecord.h b/cpp/src/qpid/broker/DtxWorkRecord.h
deleted file mode 100644
index aec2d2aed4..0000000000
--- a/cpp/src/qpid/broker/DtxWorkRecord.h
+++ /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.
- *
- */
-#ifndef _DtxWorkRecord_
-#define _DtxWorkRecord_
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/DtxBuffer.h"
-#include "qpid/broker/DtxTimeout.h"
-#include "qpid/broker/TransactionalStore.h"
-
-#include "qpid/framing/amqp_types.h"
-#include "qpid/sys/Mutex.h"
-
-#include <algorithm>
-#include <functional>
-#include <vector>
-
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-/**
- * Represents the work done under a particular distributed transaction
- * across potentially multiple channels. Identified by a xid. Allows
- * that work to be prepared, committed and rolled-back.
- */
-class DtxWorkRecord
-{
- typedef std::vector<DtxBuffer::shared_ptr> Work;
-
- const std::string xid;
- TransactionalStore* const store;
- bool completed;
- bool rolledback;
- bool prepared;
- bool expired;
- boost::intrusive_ptr<DtxTimeout> timeout;
- Work work;
- std::auto_ptr<TPCTransactionContext> txn;
- qpid::sys::Mutex lock;
-
- bool check();
- void abort();
- bool prepare(TransactionContext* txn);
-public:
- QPID_BROKER_EXTERN DtxWorkRecord(const std::string& xid,
- TransactionalStore* const store);
- QPID_BROKER_EXTERN ~DtxWorkRecord();
- QPID_BROKER_EXTERN bool prepare();
- QPID_BROKER_EXTERN bool commit(bool onePhase);
- QPID_BROKER_EXTERN void rollback();
- QPID_BROKER_EXTERN void add(DtxBuffer::shared_ptr ops);
- void recover(std::auto_ptr<TPCTransactionContext> txn, DtxBuffer::shared_ptr ops);
- void timedout();
- void setTimeout(boost::intrusive_ptr<DtxTimeout> t) { timeout = t; }
- boost::intrusive_ptr<DtxTimeout> getTimeout() { return timeout; }
-};
-
-}
-}
-
-#endif
diff --git a/cpp/src/qpid/broker/Exchange.cpp b/cpp/src/qpid/broker/Exchange.cpp
deleted file mode 100644
index 622cc81002..0000000000
--- a/cpp/src/qpid/broker/Exchange.cpp
+++ /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.
- *
- */
-
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/DeliverableMessage.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/broker/ExchangeRegistry.h"
-#include "qpid/broker/FedOps.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/framing/MessageProperties.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/sys/ExceptionHolder.h"
-#include <stdexcept>
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-using qpid::framing::Buffer;
-using qpid::framing::FieldTable;
-using qpid::sys::Mutex;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace
-{
- const std::string qpidMsgSequence("qpid.msg_sequence");
- const std::string qpidSequenceCounter("qpid.sequence_counter");
- const std::string qpidIVE("qpid.ive");
- const std::string QPID_MANAGEMENT("qpid.management");
-}
-
-
-Exchange::PreRoute::PreRoute(Deliverable& msg, Exchange* _p):parent(_p) {
- if (parent){
- if (parent->sequence || parent->ive) parent->sequenceLock.lock();
-
- if (parent->sequence){
- parent->sequenceNo++;
- msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders().setInt64(qpidMsgSequence,parent->sequenceNo);
- }
- if (parent->ive) {
- parent->lastMsg = &( msg.getMessage());
- }
- }
-}
-
-Exchange::PreRoute::~PreRoute(){
- if (parent && (parent->sequence || parent->ive)){
- parent->sequenceLock.unlock();
- }
-}
-
-namespace {
-/** Store information about an exception to be thrown later.
- * If multiple exceptions are stored, save the first of the "most severe"
- * exceptions, SESSION is les sever than CONNECTION etc.
- */
-class ExInfo {
- public:
- enum Type { NONE, SESSION, CONNECTION, OTHER };
-
- ExInfo(string exchange) : type(NONE), exchange(exchange) {}
- void store(Type type_, const qpid::sys::ExceptionHolder& exception_, const boost::shared_ptr<Queue>& queue) {
- QPID_LOG(warning, "Exchange " << exchange << " cannot deliver to queue "
- << queue->getName() << ": " << exception_.what());
- if (type < type_) { // Replace less severe exception
- type = type_;
- exception = exception_;
- }
- }
-
- void raise() {
- exception.raise();
- }
-
- private:
- Type type;
- string exchange;
- qpid::sys::ExceptionHolder exception;
-};
-}
-
-void Exchange::doRoute(Deliverable& msg, ConstBindingList b)
-{
- int count = 0;
-
- if (b.get()) {
- // Block the content release if the message is transient AND there is more than one binding
- if (!msg.getMessage().isPersistent() && b->size() > 1) {
- msg.getMessage().blockContentRelease();
- }
-
-
- ExInfo error(getName()); // Save exception to throw at the end.
- for(std::vector<Binding::shared_ptr>::const_iterator i = b->begin(); i != b->end(); i++, count++) {
- try {
- msg.deliverTo((*i)->queue);
- if ((*i)->mgmtBinding != 0)
- (*i)->mgmtBinding->inc_msgMatched();
- }
- catch (const SessionException& e) {
- error.store(ExInfo::SESSION, framing::createSessionException(e.code, e.what()),(*i)->queue);
- }
- catch (const ConnectionException& e) {
- error.store(ExInfo::CONNECTION, framing::createConnectionException(e.code, e.what()), (*i)->queue);
- }
- catch (const std::exception& e) {
- error.store(ExInfo::OTHER, qpid::sys::ExceptionHolder(new Exception(e.what())), (*i)->queue);
- }
- }
- error.raise();
- }
-
- if (mgmtExchange != 0)
- {
- mgmtExchange->inc_msgReceives ();
- mgmtExchange->inc_byteReceives (msg.contentSize ());
- if (count == 0)
- {
- //QPID_LOG(warning, "Exchange " << getName() << " could not route message; no matching binding found");
- mgmtExchange->inc_msgDrops ();
- mgmtExchange->inc_byteDrops (msg.contentSize ());
- }
- else
- {
- mgmtExchange->inc_msgRoutes (count);
- mgmtExchange->inc_byteRoutes (count * msg.contentSize ());
- }
- }
-}
-
-void Exchange::routeIVE(){
- if (ive && lastMsg.get()){
- DeliverableMessage dmsg(lastMsg);
- route(dmsg, lastMsg->getRoutingKey(), lastMsg->getApplicationHeaders());
- }
-}
-
-
-Exchange::Exchange (const string& _name, Manageable* parent, Broker* b) :
- name(_name), durable(false), persistenceId(0), sequence(false),
- sequenceNo(0), ive(false), mgmtExchange(0), broker(b), destroyed(false)
-{
- if (parent != 0 && broker != 0)
- {
- ManagementAgent* agent = broker->getManagementAgent();
- if (agent != 0)
- {
- mgmtExchange = new _qmf::Exchange (agent, this, parent, _name);
- mgmtExchange->set_durable(durable);
- mgmtExchange->set_autoDelete(false);
- agent->addObject(mgmtExchange, 0, durable);
- }
- }
-}
-
-Exchange::Exchange(const string& _name, bool _durable, const qpid::framing::FieldTable& _args,
- Manageable* parent, Broker* b)
- : name(_name), durable(_durable), alternateUsers(0), persistenceId(0),
- args(_args), sequence(false), sequenceNo(0), ive(false), mgmtExchange(0), broker(b), destroyed(false)
-{
- if (parent != 0 && broker != 0)
- {
- ManagementAgent* agent = broker->getManagementAgent();
- if (agent != 0)
- {
- mgmtExchange = new _qmf::Exchange (agent, this, parent, _name);
- mgmtExchange->set_durable(durable);
- mgmtExchange->set_autoDelete(false);
- mgmtExchange->set_arguments(ManagementAgent::toMap(args));
- agent->addObject(mgmtExchange, 0, durable);
- }
- }
-
- sequence = _args.get(qpidMsgSequence);
- if (sequence) {
- QPID_LOG(debug, "Configured exchange " << _name << " with Msg sequencing");
- args.setInt64(std::string(qpidSequenceCounter), sequenceNo);
- }
-
- ive = _args.get(qpidIVE);
- if (ive) {
- if (broker && broker->isInCluster())
- throw framing::NotImplementedException("Cannot use Initial Value Exchanges in a cluster");
- QPID_LOG(debug, "Configured exchange " << _name << " with Initial Value");
- }
-}
-
-Exchange::~Exchange ()
-{
- if (mgmtExchange != 0)
- mgmtExchange->resourceDestroy ();
-}
-
-void Exchange::setAlternate(Exchange::shared_ptr _alternate)
-{
- alternate = _alternate;
- if (mgmtExchange != 0) {
- if (alternate.get() != 0)
- mgmtExchange->set_altExchange(alternate->GetManagementObject()->getObjectId());
- else
- mgmtExchange->clr_altExchange();
- }
-}
-
-void Exchange::setPersistenceId(uint64_t id) const
-{
- persistenceId = id;
-}
-
-Exchange::shared_ptr Exchange::decode(ExchangeRegistry& exchanges, Buffer& buffer)
-{
- string name;
- string type;
- string altName;
- FieldTable args;
-
- buffer.getShortString(name);
- bool durable(buffer.getOctet());
- buffer.getShortString(type);
- buffer.get(args);
- // For backwards compatibility on restoring exchanges from before the alt-exchange update, perform check
- if (buffer.available())
- buffer.getShortString(altName);
-
- try {
- Exchange::shared_ptr exch = exchanges.declare(name, type, durable, args).first;
- exch->sequenceNo = args.getAsInt64(qpidSequenceCounter);
- exch->alternateName.assign(altName);
- return exch;
- } catch (const UnknownExchangeTypeException&) {
- QPID_LOG(warning, "Could not create exchange " << name << "; type " << type << " is not recognised");
- return Exchange::shared_ptr();
- }
-}
-
-void Exchange::encode(Buffer& buffer) const
-{
- buffer.putShortString(name);
- buffer.putOctet(durable);
- buffer.putShortString(getType());
- if (args.isSet(qpidSequenceCounter))
- args.setInt64(std::string(qpidSequenceCounter),sequenceNo);
- buffer.put(args);
- buffer.putShortString(alternate.get() ? alternate->getName() : string(""));
-}
-
-uint32_t Exchange::encodedSize() const
-{
- return name.size() + 1/*short string size*/
- + 1 /*durable*/
- + getType().size() + 1/*short string size*/
- + (alternate.get() ? alternate->getName().size() : 0) + 1/*short string size*/
- + args.encodedSize();
-}
-
-void Exchange::recoveryComplete(ExchangeRegistry& exchanges)
-{
- if (!alternateName.empty()) {
- try {
- Exchange::shared_ptr ae = exchanges.get(alternateName);
- setAlternate(ae);
- } catch (const NotFoundException&) {
- QPID_LOG(warning, "Could not set alternate exchange \"" << alternateName << "\": does not exist.");
- }
- }
-}
-
-ManagementObject* Exchange::GetManagementObject (void) const
-{
- return (ManagementObject*) mgmtExchange;
-}
-
-void Exchange::registerDynamicBridge(DynamicBridge* db)
-{
- if (!supportsDynamicBinding())
- throw Exception("Exchange type does not support dynamic binding");
-
- {
- Mutex::ScopedLock l(bridgeLock);
- for (std::vector<DynamicBridge*>::iterator iter = bridgeVector.begin();
- iter != bridgeVector.end(); iter++)
- (*iter)->sendReorigin();
-
- bridgeVector.push_back(db);
- }
-
- FieldTable args;
- args.setString(qpidFedOp, fedOpReorigin);
- bind(Queue::shared_ptr(), string(), &args);
-}
-
-void Exchange::removeDynamicBridge(DynamicBridge* db)
-{
- Mutex::ScopedLock l(bridgeLock);
- for (std::vector<DynamicBridge*>::iterator iter = bridgeVector.begin();
- iter != bridgeVector.end(); iter++)
- if (*iter == db) {
- bridgeVector.erase(iter);
- break;
- }
-}
-
-void Exchange::handleHelloRequest()
-{
-}
-
-void Exchange::propagateFedOp(const string& routingKey, const string& tags, const string& op, const string& origin, qpid::framing::FieldTable* extra_args)
-{
- Mutex::ScopedLock l(bridgeLock);
- string myOp(op.empty() ? fedOpBind : op);
-
- for (std::vector<DynamicBridge*>::iterator iter = bridgeVector.begin();
- iter != bridgeVector.end(); iter++)
- (*iter)->propagateBinding(routingKey, tags, op, origin, extra_args);
-}
-
-Exchange::Binding::Binding(const string& _key, Queue::shared_ptr _queue, Exchange* _parent,
- FieldTable _args, const string& _origin)
- : parent(_parent), queue(_queue), key(_key), args(_args), origin(_origin), mgmtBinding(0)
-{
-}
-
-Exchange::Binding::~Binding ()
-{
- if (mgmtBinding != 0) {
- ManagementObject* mo = queue->GetManagementObject();
- if (mo != 0)
- static_cast<_qmf::Queue*>(mo)->dec_bindingCount();
- mgmtBinding->resourceDestroy ();
- }
-}
-
-void Exchange::Binding::startManagement()
-{
- if (parent != 0)
- {
- Broker* broker = parent->getBroker();
- if (broker != 0) {
- ManagementAgent* agent = broker->getManagementAgent();
- if (agent != 0) {
- ManagementObject* mo = queue->GetManagementObject();
- if (mo != 0) {
- management::ObjectId queueId = mo->getObjectId();
-
- mgmtBinding = new _qmf::Binding
- (agent, this, (Manageable*) parent, queueId, key, ManagementAgent::toMap(args));
- if (!origin.empty())
- mgmtBinding->set_origin(origin);
- agent->addObject(mgmtBinding);
- static_cast<_qmf::Queue*>(mo)->inc_bindingCount();
- }
- }
- }
- }
-}
-
-ManagementObject* Exchange::Binding::GetManagementObject () const
-{
- return (ManagementObject*) mgmtBinding;
-}
-
-Exchange::MatchQueue::MatchQueue(Queue::shared_ptr q) : queue(q) {}
-
-bool Exchange::MatchQueue::operator()(Exchange::Binding::shared_ptr b)
-{
- return b->queue == queue;
-}
-
-void Exchange::setProperties(const boost::intrusive_ptr<Message>& msg) {
- msg->getProperties<DeliveryProperties>()->setExchange(getName());
-}
-
-bool Exchange::routeWithAlternate(Deliverable& msg)
-{
- route(msg, msg.getMessage().getRoutingKey(), msg.getMessage().getApplicationHeaders());
- if (!msg.delivered && alternate) {
- alternate->route(msg, msg.getMessage().getRoutingKey(), msg.getMessage().getApplicationHeaders());
- }
- return msg.delivered;
-}
diff --git a/cpp/src/qpid/broker/Exchange.h b/cpp/src/qpid/broker/Exchange.h
deleted file mode 100644
index b12af9a1dd..0000000000
--- a/cpp/src/qpid/broker/Exchange.h
+++ /dev/null
@@ -1,248 +0,0 @@
-#ifndef _broker_Exchange_h
-#define _broker_Exchange_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/shared_ptr.hpp>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Deliverable.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/PersistableExchange.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/management/Manageable.h"
-#include "qmf/org/apache/qpid/broker/Exchange.h"
-#include "qmf/org/apache/qpid/broker/Binding.h"
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-class ExchangeRegistry;
-
-class QPID_BROKER_CLASS_EXTERN Exchange : public PersistableExchange, public management::Manageable {
-public:
- struct Binding : public management::Manageable {
- typedef boost::shared_ptr<Binding> shared_ptr;
- typedef std::vector<Binding::shared_ptr> vector;
-
- Exchange* parent;
- boost::shared_ptr<Queue> queue;
- const std::string key;
- const framing::FieldTable args;
- std::string origin;
- qmf::org::apache::qpid::broker::Binding* mgmtBinding;
-
- Binding(const std::string& key, boost::shared_ptr<Queue> queue, Exchange* parent = 0,
- framing::FieldTable args = framing::FieldTable(), const std::string& origin = std::string());
- ~Binding();
- void startManagement();
- management::ManagementObject* GetManagementObject() const;
- };
-
-private:
- const std::string name;
- const bool durable;
- std::string alternateName;
- boost::shared_ptr<Exchange> alternate;
- uint32_t alternateUsers;
- mutable uint64_t persistenceId;
-
-protected:
- mutable qpid::framing::FieldTable args;
- bool sequence;
- mutable qpid::sys::Mutex sequenceLock;
- int64_t sequenceNo;
- bool ive;
- boost::intrusive_ptr<Message> lastMsg;
-
- class PreRoute{
- public:
- PreRoute(Deliverable& msg, Exchange* _p);
- ~PreRoute();
- private:
- Exchange* parent;
- };
-
- typedef boost::shared_ptr<const std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> > > ConstBindingList;
- typedef boost::shared_ptr< std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> > > BindingList;
- void doRoute(Deliverable& msg, ConstBindingList b);
- void routeIVE();
-
-
- struct MatchQueue {
- const boost::shared_ptr<Queue> queue;
- MatchQueue(boost::shared_ptr<Queue> q);
- bool operator()(Exchange::Binding::shared_ptr b);
- };
-
- /** A FedBinding keeps track of information that Federation needs
- to know when to propagate changes.
-
- Dynamic federation needs to know which exchanges have at least
- one local binding. The bindings on these exchanges need to be
- propagated.
-
- Federated binds and unbinds need to know which federation
- origins are associated with the bindings for each queue. When
- origins are added or deleted, the corresponding bindings need
- to be propagated.
-
- fedBindings[queueName] contains the origins associated with
- the given queue.
- */
-
- class FedBinding {
- uint32_t localBindings;
-
- typedef std::set<std::string> originSet;
- std::map<std::string, originSet> fedBindings;
-
- public:
- FedBinding() : localBindings(0) {}
- bool hasLocal() const { return localBindings != 0; }
-
- /** Returns true if propagation is needed. */
- bool addOrigin(const std::string& queueName, const std::string& origin) {
- if (origin.empty()) {
- localBindings++;
- return localBindings == 1;
- }
- fedBindings[queueName].insert(origin);
- return true;
- }
-
- /** Returns true if propagation is needed. */
- bool delOrigin(const std::string& queueName, const std::string& origin){
- if (origin.empty()) { // no remote == local binding
- if (localBindings > 0)
- localBindings--;
- return localBindings == 0;
- }
- size_t match = fedBindings[queueName].erase(origin);
- if (fedBindings[queueName].empty())
- fedBindings.erase(queueName);
- return match != 0;
- }
-
- uint32_t count() {
- return localBindings + fedBindings.size();
- }
-
- uint32_t countFedBindings(const std::string& queueName) {
- // don't use '[]' - it may increase size of fedBindings!
- std::map<std::string, originSet>::iterator i;
- if ((i = fedBindings.find(queueName)) != fedBindings.end())
- return i->second.size();
- return 0;
- }
- };
-
- qmf::org::apache::qpid::broker::Exchange* mgmtExchange;
-
-public:
- typedef boost::shared_ptr<Exchange> shared_ptr;
-
- QPID_BROKER_EXTERN explicit Exchange(const std::string& name, management::Manageable* parent = 0,
- Broker* broker = 0);
- QPID_BROKER_EXTERN Exchange(const std::string& _name, bool _durable, const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0, Broker* broker = 0);
- QPID_BROKER_INLINE_EXTERN virtual ~Exchange();
-
- const std::string& getName() const { return name; }
- bool isDurable() { return durable; }
- qpid::framing::FieldTable& getArgs() { return args; }
-
- Exchange::shared_ptr getAlternate() { return alternate; }
- void setAlternate(Exchange::shared_ptr _alternate);
- void incAlternateUsers() { alternateUsers++; }
- void decAlternateUsers() { alternateUsers--; }
- bool inUseAsAlternate() { return alternateUsers > 0; }
-
- virtual std::string getType() const = 0;
-
- /**
- * bind() is used for two distinct purposes:
- *
- * 1. To create a binding, in the conventional sense
- *
- * 2. As a vehicle for any FedOp, currently including federated
- * binding, federated unbinding, federated reorigin.
- *
- */
-
- virtual bool bind(boost::shared_ptr<Queue> queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
- virtual bool unbind(boost::shared_ptr<Queue> queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
- virtual bool isBound(boost::shared_ptr<Queue> queue, const std::string* const routingKey, const qpid::framing::FieldTable* const args) = 0;
- QPID_BROKER_EXTERN virtual void setProperties(const boost::intrusive_ptr<Message>&);
- virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
-
- //PersistableExchange:
- QPID_BROKER_EXTERN void setPersistenceId(uint64_t id) const;
- uint64_t getPersistenceId() const { return persistenceId; }
- QPID_BROKER_EXTERN uint32_t encodedSize() const;
- QPID_BROKER_EXTERN virtual void encode(framing::Buffer& buffer) const;
-
- static QPID_BROKER_EXTERN Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer);
-
- // Manageable entry points
- QPID_BROKER_EXTERN management::ManagementObject* GetManagementObject(void) const;
-
- // Federation hooks
- class DynamicBridge {
- public:
- virtual ~DynamicBridge() {}
- virtual void propagateBinding(const std::string& key, const std::string& tagList, const std::string& op, const std::string& origin, qpid::framing::FieldTable* extra_args=0) = 0;
- virtual void sendReorigin() = 0;
- virtual bool containsLocalTag(const std::string& tagList) const = 0;
- virtual const std::string& getLocalTag() const = 0;
- };
-
- void registerDynamicBridge(DynamicBridge* db);
- void removeDynamicBridge(DynamicBridge* db);
- virtual bool supportsDynamicBinding() { return false; }
- Broker* getBroker() const { return broker; }
- /**
- * Notify exchange that recovery has completed.
- */
- void recoveryComplete(ExchangeRegistry& exchanges);
-
- bool routeWithAlternate(Deliverable& message);
-
- void destroy() { destroyed = true; }
- bool isDestroyed() const { return destroyed; }
-
-protected:
- qpid::sys::Mutex bridgeLock;
- std::vector<DynamicBridge*> bridgeVector;
- Broker* broker;
- bool destroyed;
-
- QPID_BROKER_EXTERN virtual void handleHelloRequest();
- void propagateFedOp(const std::string& routingKey, const std::string& tags,
- const std::string& op, const std::string& origin,
- qpid::framing::FieldTable* extra_args=0);
-};
-
-}}
-
-#endif /*!_broker_Exchange.cpp_h*/
diff --git a/cpp/src/qpid/broker/ExchangeRegistry.cpp b/cpp/src/qpid/broker/ExchangeRegistry.cpp
deleted file mode 100644
index 1c8d26c4f7..0000000000
--- a/cpp/src/qpid/broker/ExchangeRegistry.cpp
+++ /dev/null
@@ -1,116 +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.
- *
- */
-
-#include "qpid/broker/ExchangeRegistry.h"
-#include "qpid/broker/DirectExchange.h"
-#include "qpid/broker/FanOutExchange.h"
-#include "qpid/broker/HeadersExchange.h"
-#include "qpid/broker/TopicExchange.h"
-#include "qpid/management/ManagementDirectExchange.h"
-#include "qpid/management/ManagementTopicExchange.h"
-#include "qpid/framing/reply_exceptions.h"
-
-using namespace qpid::broker;
-using namespace qpid::sys;
-using std::pair;
-using std::string;
-using qpid::framing::FieldTable;
-
-pair<Exchange::shared_ptr, bool> ExchangeRegistry::declare(const string& name, const string& type){
-
- return declare(name, type, false, FieldTable());
-}
-
-pair<Exchange::shared_ptr, bool> ExchangeRegistry::declare(const string& name, const string& type,
- bool durable, const FieldTable& args){
- RWlock::ScopedWlock locker(lock);
- ExchangeMap::iterator i = exchanges.find(name);
- if (i == exchanges.end()) {
- Exchange::shared_ptr exchange;
-
- if (type == TopicExchange::typeName){
- exchange = Exchange::shared_ptr(new TopicExchange(name, durable, args, parent, broker));
- }else if(type == DirectExchange::typeName){
- exchange = Exchange::shared_ptr(new DirectExchange(name, durable, args, parent, broker));
- }else if(type == FanOutExchange::typeName){
- exchange = Exchange::shared_ptr(new FanOutExchange(name, durable, args, parent, broker));
- }else if (type == HeadersExchange::typeName) {
- exchange = Exchange::shared_ptr(new HeadersExchange(name, durable, args, parent, broker));
- }else if (type == ManagementDirectExchange::typeName) {
- exchange = Exchange::shared_ptr(new ManagementDirectExchange(name, durable, args, parent, broker));
- }else if (type == ManagementTopicExchange::typeName) {
- exchange = Exchange::shared_ptr(new ManagementTopicExchange(name, durable, args, parent, broker));
- }else{
- FunctionMap::iterator i = factory.find(type);
- if (i == factory.end()) {
- throw UnknownExchangeTypeException();
- } else {
- exchange = i->second(name, durable, args, parent, broker);
- }
- }
- exchanges[name] = exchange;
- return std::pair<Exchange::shared_ptr, bool>(exchange, true);
- } else {
- return std::pair<Exchange::shared_ptr, bool>(i->second, false);
- }
-}
-
-void ExchangeRegistry::destroy(const string& name){
- if (name.empty() ||
- (name.find("amq.") == 0 &&
- (name == "amq.direct" || name == "amq.fanout" || name == "amq.topic" || name == "amq.match")) ||
- name == "qpid.management")
- throw framing::NotAllowedException(QPID_MSG("Cannot delete default exchange: '" << name << "'"));
- RWlock::ScopedWlock locker(lock);
- ExchangeMap::iterator i = exchanges.find(name);
- if (i != exchanges.end()) {
- i->second->destroy();
- exchanges.erase(i);
- }
-}
-
-Exchange::shared_ptr ExchangeRegistry::get(const string& name){
- RWlock::ScopedRlock locker(lock);
- ExchangeMap::iterator i = exchanges.find(name);
- if (i == exchanges.end())
- throw framing::NotFoundException(QPID_MSG("Exchange not found: " << name));
- return i->second;
-}
-
-bool ExchangeRegistry::registerExchange(const Exchange::shared_ptr& ex) {
- return exchanges.insert(ExchangeMap::value_type(ex->getName(), ex)).second;
-}
-
-void ExchangeRegistry::registerType(const std::string& type, FactoryFunction f)
-{
- factory[type] = f;
-}
-
-
-namespace
-{
-const std::string empty;
-}
-
-Exchange::shared_ptr ExchangeRegistry::getDefault()
-{
- return get(empty);
-}
diff --git a/cpp/src/qpid/broker/ExchangeRegistry.h b/cpp/src/qpid/broker/ExchangeRegistry.h
deleted file mode 100644
index 2b75a8f3cf..0000000000
--- a/cpp/src/qpid/broker/ExchangeRegistry.h
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef _broker_ExchangeRegistry_h
-#define _broker_ExchangeRegistry_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/management/Manageable.h"
-
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-
-#include <algorithm>
-#include <map>
-
-namespace qpid {
-namespace broker {
-
-struct UnknownExchangeTypeException{};
-
-class ExchangeRegistry{
- public:
- typedef boost::function5<Exchange::shared_ptr, const std::string&,
- bool, const qpid::framing::FieldTable&, qpid::management::Manageable*, qpid::broker::Broker*> FactoryFunction;
-
- ExchangeRegistry (Broker* b = 0) : parent(0), broker(b) {}
- QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare
- (const std::string& name, const std::string& type);
- QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare
- (const std::string& name,
- const std::string& type,
- bool durable,
- const qpid::framing::FieldTable& args = framing::FieldTable());
- QPID_BROKER_EXTERN void destroy(const std::string& name);
- QPID_BROKER_EXTERN Exchange::shared_ptr get(const std::string& name);
- Exchange::shared_ptr getDefault();
-
- /**
- * Register the manageable parent for declared exchanges
- */
- void setParent (management::Manageable* _parent) { parent = _parent; }
-
- /** Register an exchange instance.
- *@return true if registered, false if exchange with same name is already registered.
- */
- bool registerExchange(const Exchange::shared_ptr&);
-
- QPID_BROKER_EXTERN void registerType(const std::string& type, FactoryFunction);
-
- /** Call f for each exchange in the registry. */
- template <class F> void eachExchange(F f) const {
- qpid::sys::RWlock::ScopedRlock l(lock);
- for (ExchangeMap::const_iterator i = exchanges.begin(); i != exchanges.end(); ++i)
- f(i->second);
- }
-
- private:
- typedef std::map<std::string, Exchange::shared_ptr> ExchangeMap;
- typedef std::map<std::string, FactoryFunction > FunctionMap;
-
- ExchangeMap exchanges;
- FunctionMap factory;
- mutable qpid::sys::RWlock lock;
- management::Manageable* parent;
- Broker* broker;
-};
-
-}} // namespace qpid::broker
-
-
-#endif /*!_broker_ExchangeRegistry_h*/
diff --git a/cpp/src/qpid/broker/ExpiryPolicy.cpp b/cpp/src/qpid/broker/ExpiryPolicy.cpp
deleted file mode 100644
index 64a12d918a..0000000000
--- a/cpp/src/qpid/broker/ExpiryPolicy.cpp
+++ /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.
- *
- */
-#include "qpid/broker/ExpiryPolicy.h"
-#include "qpid/broker/Message.h"
-#include "qpid/sys/Time.h"
-
-namespace qpid {
-namespace broker {
-
-ExpiryPolicy::~ExpiryPolicy() {}
-
-void ExpiryPolicy::willExpire(Message&) {}
-
-bool ExpiryPolicy::hasExpired(Message& m) {
- return m.getExpiration() < sys::AbsTime::now();
-}
-
-void ExpiryPolicy::forget(Message&) {}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/ExpiryPolicy.h b/cpp/src/qpid/broker/ExpiryPolicy.h
deleted file mode 100644
index a723eb0aa8..0000000000
--- a/cpp/src/qpid/broker/ExpiryPolicy.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef QPID_BROKER_EXPIRYPOLICY_H
-#define QPID_BROKER_EXPIRYPOLICY_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/RefCounted.h"
-#include "qpid/broker/BrokerImportExport.h"
-
-namespace qpid {
-namespace broker {
-
-class Message;
-
-/**
- * Default expiry policy.
- */
-class QPID_BROKER_CLASS_EXTERN ExpiryPolicy : public RefCounted
-{
- public:
- QPID_BROKER_EXTERN virtual ~ExpiryPolicy();
- QPID_BROKER_EXTERN virtual void willExpire(Message&);
- QPID_BROKER_EXTERN virtual bool hasExpired(Message&);
- QPID_BROKER_EXTERN virtual void forget(Message&);
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_EXPIRYPOLICY_H*/
diff --git a/cpp/src/qpid/broker/Fairshare.cpp b/cpp/src/qpid/broker/Fairshare.cpp
deleted file mode 100644
index 17270ffd8d..0000000000
--- a/cpp/src/qpid/broker/Fairshare.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/Fairshare.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/log/Statement.h"
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/assign/list_of.hpp>
-
-namespace qpid {
-namespace broker {
-
-Fairshare::Fairshare(size_t levels, uint limit) :
- PriorityQueue(levels),
- limits(levels, limit), priority(levels-1), count(0) {}
-
-
-void Fairshare::setLimit(size_t level, uint limit)
-{
- limits[level] = limit;
-}
-
-bool Fairshare::limitReached()
-{
- uint l = limits[priority];
- return l && ++count > l;
-}
-
-uint Fairshare::currentLevel()
-{
- if (limitReached()) {
- return nextLevel();
- } else {
- return priority;
- }
-}
-
-uint Fairshare::nextLevel()
-{
- count = 1;
- if (priority) --priority;
- else priority = levels-1;
- return priority;
-}
-
-bool Fairshare::isNull()
-{
- for (int i = 0; i < levels; i++) if (limits[i]) return false;
- return true;
-}
-
-bool Fairshare::getState(uint& p, uint& c) const
-{
- p = priority;
- c = count;
- return true;
-}
-
-bool Fairshare::setState(uint p, uint c)
-{
- priority = p;
- count = c;
- return true;
-}
-
-bool Fairshare::findFrontLevel(uint& p, PriorityLevels& messages)
-{
- const uint start = p = currentLevel();
- do {
- if (!messages[p].empty()) return true;
- } while ((p = nextLevel()) != start);
- return false;
-}
-
-
-
-bool Fairshare::getState(const Messages& m, uint& priority, uint& count)
-{
- const Fairshare* fairshare = dynamic_cast<const Fairshare*>(&m);
- return fairshare && fairshare->getState(priority, count);
-}
-
-bool Fairshare::setState(Messages& m, uint priority, uint count)
-{
- Fairshare* fairshare = dynamic_cast<Fairshare*>(&m);
- return fairshare && fairshare->setState(priority, count);
-}
-
-int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::vector<std::string>& keys)
-{
- qpid::framing::FieldTable::ValuePtr v;
- std::vector<std::string>::const_iterator i = keys.begin();
- while (!v && i != keys.end()) {
- v = settings.get(*i++);
- }
-
- if (!v) {
- return 0;
- } else if (v->convertsTo<int>()) {
- return v->get<int>();
- } else if (v->convertsTo<std::string>()){
- std::string s = v->get<std::string>();
- try {
- return boost::lexical_cast<int>(s);
- } catch(const boost::bad_lexical_cast&) {
- QPID_LOG(warning, "Ignoring invalid integer value for " << *i << ": " << s);
- return 0;
- }
- } else {
- QPID_LOG(warning, "Ignoring invalid integer value for " << *i << ": " << *v);
- return 0;
- }
-}
-
-int getIntegerSettingForKey(const qpid::framing::FieldTable& settings, const std::string& key)
-{
- return getIntegerSetting(settings, boost::assign::list_of<std::string>(key));
-}
-
-int getSetting(const qpid::framing::FieldTable& settings, const std::vector<std::string>& keys, int minvalue, int maxvalue)
-{
- return std::max(minvalue,std::min(getIntegerSetting(settings, keys), maxvalue));
-}
-
-std::auto_ptr<Fairshare> getFairshareForKey(const qpid::framing::FieldTable& settings, uint levels, const std::string& key)
-{
- uint defaultLimit = getIntegerSettingForKey(settings, key);
- std::auto_ptr<Fairshare> fairshare(new Fairshare(levels, defaultLimit));
- for (uint i = 0; i < levels; i++) {
- std::string levelKey = (boost::format("%1%-%2%") % key % i).str();
- if(settings.isSet(levelKey)) {
- fairshare->setLimit(i, getIntegerSettingForKey(settings, levelKey));
- }
- }
- if (!fairshare->isNull()) {
- return fairshare;
- } else {
- return std::auto_ptr<Fairshare>();
- }
-}
-
-std::auto_ptr<Fairshare> getFairshare(const qpid::framing::FieldTable& settings,
- uint levels,
- const std::vector<std::string>& keys)
-{
- std::auto_ptr<Fairshare> fairshare;
- for (std::vector<std::string>::const_iterator i = keys.begin(); i != keys.end() && !fairshare.get(); ++i) {
- fairshare = getFairshareForKey(settings, levels, *i);
- }
- return fairshare;
-}
-
-std::auto_ptr<Messages> Fairshare::create(const qpid::framing::FieldTable& settings)
-{
- using boost::assign::list_of;
- std::auto_ptr<Messages> result;
- size_t levels = getSetting(settings, list_of<std::string>("qpid.priorities")("x-qpid-priorities"), 1, 100);
- if (levels) {
- std::auto_ptr<Fairshare> fairshare =
- getFairshare(settings, levels, list_of<std::string>("qpid.fairshare")("x-qpid-fairshare"));
- if (fairshare.get()) result = fairshare;
- else result = std::auto_ptr<Messages>(new PriorityQueue(levels));
- }
- return result;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/Fairshare.h b/cpp/src/qpid/broker/Fairshare.h
deleted file mode 100644
index 1b25721e0c..0000000000
--- a/cpp/src/qpid/broker/Fairshare.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef QPID_BROKER_FAIRSHARE_H
-#define QPID_BROKER_FAIRSHARE_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/PriorityQueue.h"
-
-namespace qpid {
-namespace framing {
-class FieldTable;
-}
-namespace broker {
-
-/**
- * Modifies a basic prioirty queue by limiting the number of messages
- * from each priority level that are dispatched before allowing
- * dispatch from the next level.
- */
-class Fairshare : public PriorityQueue
-{
- public:
- Fairshare(size_t levels, uint limit);
- bool getState(uint& priority, uint& count) const;
- bool setState(uint priority, uint count);
- void setLimit(size_t level, uint limit);
- bool isNull();
- static std::auto_ptr<Messages> create(const qpid::framing::FieldTable& settings);
- static bool getState(const Messages&, uint& priority, uint& count);
- static bool setState(Messages&, uint priority, uint count);
- private:
- std::vector<uint> limits;
-
- uint priority;
- uint count;
-
- uint currentLevel();
- uint nextLevel();
- bool limitReached();
- bool findFrontLevel(uint& p, PriorityLevels&);
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_FAIRSHARE_H*/
diff --git a/cpp/src/qpid/broker/FanOutExchange.cpp b/cpp/src/qpid/broker/FanOutExchange.cpp
deleted file mode 100644
index 5879fa0892..0000000000
--- a/cpp/src/qpid/broker/FanOutExchange.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/log/Statement.h"
-#include "qpid/broker/FanOutExchange.h"
-#include "qpid/broker/FedOps.h"
-#include <algorithm>
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-using namespace qpid::sys;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-FanOutExchange::FanOutExchange(const std::string& _name, Manageable* _parent, Broker* b) :
- Exchange(_name, _parent, b)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type (typeName);
-}
-
-FanOutExchange::FanOutExchange(const std::string& _name, bool _durable,
- const FieldTable& _args, Manageable* _parent, Broker* b) :
- Exchange(_name, _durable, _args, _parent, b)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type (typeName);
-}
-
-bool FanOutExchange::bind(Queue::shared_ptr queue, const string& /*key*/, const FieldTable* args)
-{
- string fedOp(args ? args->getAsString(qpidFedOp) : fedOpBind);
- string fedTags(args ? args->getAsString(qpidFedTags) : "");
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- bool propagate = false;
-
- if (args == 0 || fedOp.empty() || fedOp == fedOpBind) {
- Binding::shared_ptr binding (new Binding ("", queue, this, FieldTable(), fedOrigin));
- if (bindings.add_unless(binding, MatchQueue(queue))) {
- binding->startManagement();
- propagate = fedBinding.addOrigin(queue->getName(), fedOrigin);
- if (mgmtExchange != 0) {
- mgmtExchange->inc_bindingCount();
- }
- } else {
- // queue already present - still need to track fedOrigin
- fedBinding.addOrigin(queue->getName(), fedOrigin);
- return false;
- }
- } else if (fedOp == fedOpUnbind) {
- propagate = fedBinding.delOrigin(queue->getName(), fedOrigin);
- if (fedBinding.countFedBindings(queue->getName()) == 0)
- unbind(queue, "", args);
- } else if (fedOp == fedOpReorigin) {
- if (fedBinding.hasLocal()) {
- propagateFedOp(string(), string(), fedOpBind, string());
- }
- }
-
- routeIVE();
- if (propagate)
- propagateFedOp(string(), fedTags, fedOp, fedOrigin);
- return true;
-}
-
-bool FanOutExchange::unbind(Queue::shared_ptr queue, const string& /*key*/, const FieldTable* args)
-{
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- bool propagate = false;
-
- QPID_LOG(debug, "Unbinding queue " << queue->getName()
- << " from exchange " << getName() << " origin=" << fedOrigin << ")" );
-
- if (bindings.remove_if(MatchQueue(queue))) {
- propagate = fedBinding.delOrigin(queue->getName(), fedOrigin);
- if (mgmtExchange != 0) {
- mgmtExchange->dec_bindingCount();
- }
- } else {
- return false;
- }
-
- if (propagate)
- propagateFedOp(string(), string(), fedOpUnbind, string());
- return true;
-}
-
-void FanOutExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* /*args*/)
-{
- PreRoute pr(msg, this);
- doRoute(msg, bindings.snapshot());
-}
-
-bool FanOutExchange::isBound(Queue::shared_ptr queue, const string* const, const FieldTable* const)
-{
- BindingsArray::ConstPtr ptr = bindings.snapshot();
- return ptr && std::find_if(ptr->begin(), ptr->end(), MatchQueue(queue)) != ptr->end();
-}
-
-
-FanOutExchange::~FanOutExchange() {}
-
-const std::string FanOutExchange::typeName("fanout");
diff --git a/cpp/src/qpid/broker/FanOutExchange.h b/cpp/src/qpid/broker/FanOutExchange.h
deleted file mode 100644
index 1a7d486796..0000000000
--- a/cpp/src/qpid/broker/FanOutExchange.h
+++ /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.
- *
- */
-#ifndef _FanOutExchange_
-#define _FanOutExchange_
-
-#include <map>
-#include <vector>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/CopyOnWriteArray.h"
-#include "qpid/broker/Queue.h"
-
-namespace qpid {
-namespace broker {
-
-class FanOutExchange : public virtual Exchange {
- typedef qpid::sys::CopyOnWriteArray<Binding::shared_ptr> BindingsArray;
- BindingsArray bindings;
- FedBinding fedBinding;
- public:
- static const std::string typeName;
-
- QPID_BROKER_EXTERN FanOutExchange(const std::string& name,
- management::Manageable* parent = 0, Broker* broker = 0);
- QPID_BROKER_EXTERN FanOutExchange(const std::string& _name,
- bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0, Broker* broker = 0);
-
- virtual std::string getType() const { return typeName; }
-
- QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
-
- virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
-
- QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
-
- QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
- const std::string* const routingKey,
- const qpid::framing::FieldTable* const args);
-
- QPID_BROKER_EXTERN virtual ~FanOutExchange();
- virtual bool supportsDynamicBinding() { return true; }
-};
-
-}
-}
-
-
-
-#endif
diff --git a/cpp/src/qpid/broker/FedOps.h b/cpp/src/qpid/broker/FedOps.h
deleted file mode 100644
index dc4a38e244..0000000000
--- a/cpp/src/qpid/broker/FedOps.h
+++ /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.
- *
- */
-
-/*
- * Strings used to identify federated operations and operands.
- */
-
-namespace
-{
- const std::string qpidFedOp("qpid.fed.op"); // a federation primitive
- const std::string qpidFedTags("qpid.fed.tags"); // a unique id for a broker
- const std::string qpidFedOrigin("qpid.fed.origin"); // the tag of the broker on which a propagated binding originated
-
- // Operands for qpidFedOp - each identifies a federation primitive
-
- const std::string fedOpBind("B");
- const std::string fedOpUnbind("U");
- const std::string fedOpReorigin("R");
- const std::string fedOpHello("H");
-}
diff --git a/cpp/src/qpid/broker/HandlerImpl.h b/cpp/src/qpid/broker/HandlerImpl.h
deleted file mode 100644
index aae636e818..0000000000
--- a/cpp/src/qpid/broker/HandlerImpl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _broker_HandlerImpl_h
-#define _broker_HandlerImpl_h
-
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "qpid/broker/SemanticState.h"
-#include "qpid/broker/SessionContext.h"
-#include "qpid/broker/ConnectionState.h"
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-
-/**
- * Base template for protocol handler implementations.
- * Provides convenience methods for getting common session objects.
- */
-class HandlerImpl {
- protected:
- SemanticState& state;
- SessionContext& session;
-
- HandlerImpl(SemanticState& s) : state(s), session(s.getSession()) {}
-
- framing::AMQP_ClientProxy& getProxy() { return session.getProxy(); }
- ConnectionState& getConnection() { return session.getConnection(); }
- Broker& getBroker() { return session.getConnection().getBroker(); }
-};
-
-}} // namespace qpid::broker
-
-
-
-#endif /*!_broker_HandlerImpl_h*/
-
-
diff --git a/cpp/src/qpid/broker/HeadersExchange.cpp b/cpp/src/qpid/broker/HeadersExchange.cpp
deleted file mode 100644
index abcaa5f69d..0000000000
--- a/cpp/src/qpid/broker/HeadersExchange.cpp
+++ /dev/null
@@ -1,341 +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.
- *
- */
-#include "qpid/broker/HeadersExchange.h"
-#include "qpid/framing/FieldValue.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include <algorithm>
-
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-using namespace qpid::sys;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-// TODO aconway 2006-09-20: More efficient matching algorithm.
-// The current search algorithm really sucks.
-// Fieldtables are heavy, maybe use shared_ptr to do handle-body.
-
-using namespace qpid::broker;
-
-namespace {
- const std::string x_match("x-match");
- // possible values for x-match
- const std::string all("all");
- const std::string any("any");
- const std::string empty;
-
- // federation related args and values
- const std::string qpidFedOp("qpid.fed.op");
- const std::string qpidFedTags("qpid.fed.tags");
- const std::string qpidFedOrigin("qpid.fed.origin");
-
- const std::string fedOpBind("B");
- const std::string fedOpUnbind("U");
- const std::string fedOpReorigin("R");
- const std::string fedOpHello("H");
-}
-
-HeadersExchange::HeadersExchange(const string& _name, Manageable* _parent, Broker* b) :
- Exchange(_name, _parent, b)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type (typeName);
-}
-
-HeadersExchange::HeadersExchange(const std::string& _name, bool _durable,
- const FieldTable& _args, Manageable* _parent, Broker* b) :
- Exchange(_name, _durable, _args, _parent, b)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type (typeName);
-}
-
-std::string HeadersExchange::getMatch(const FieldTable* args)
-{
- if (!args) {
- throw InternalErrorException(QPID_MSG("No arguments given."));
- }
- FieldTable::ValuePtr what = args->get(x_match);
- if (!what) {
- return empty;
- }
- if (!what->convertsTo<std::string>()) {
- throw InternalErrorException(QPID_MSG("Invalid x-match binding format to headers exchange. Must be a string [\"all\" or \"any\"]"));
- }
- return what->get<std::string>();
-}
-
-bool HeadersExchange::bind(Queue::shared_ptr queue, const string& bindingKey, const FieldTable* args)
-{
- string fedOp(fedOpBind);
- string fedTags;
- string fedOrigin;
- if (args) {
- fedOp = args->getAsString(qpidFedOp);
- fedTags = args->getAsString(qpidFedTags);
- fedOrigin = args->getAsString(qpidFedOrigin);
- }
-
- bool propagate = false;
-
- // The federation args get propagated directly, so we need to identify
- // the non federation args in case a federated propagate is needed
- FieldTable extra_args;
- getNonFedArgs(args, extra_args);
-
- if (fedOp.empty() || fedOp == fedOpBind) {
- // x-match arg MUST be present for a bind call
- std::string x_match_value = getMatch(args);
-
- if (x_match_value != all && x_match_value != any) {
- throw InternalErrorException(QPID_MSG("Invalid or missing x-match value binding to headers exchange. Must be a string [\"all\" or \"any\"]"));
- }
-
- {
- Mutex::ScopedLock l(lock);
- Binding::shared_ptr binding (new Binding (bindingKey, queue, this, *args));
- BoundKey bk(binding);
- if (bindings.add_unless(bk, MatchArgs(queue, args))) {
- binding->startManagement();
- propagate = bk.fedBinding.addOrigin(queue->getName(), fedOrigin);
- if (mgmtExchange != 0) {
- mgmtExchange->inc_bindingCount();
- }
- } else {
- bk.fedBinding.addOrigin(queue->getName(), fedOrigin);
- return false;
- }
- } // lock dropped
-
- } else if (fedOp == fedOpUnbind) {
- Mutex::ScopedLock l(lock);
-
- FedUnbindModifier modifier(queue->getName(), fedOrigin);
- bindings.modify_if(MatchKey(queue, bindingKey), modifier);
- propagate = modifier.shouldPropagate;
- if (modifier.shouldUnbind) {
- unbind(queue, bindingKey, args);
- }
-
- } else if (fedOp == fedOpReorigin) {
- Bindings::ConstPtr p = bindings.snapshot();
- if (p.get())
- {
- Mutex::ScopedLock l(lock);
- for (std::vector<BoundKey>::const_iterator i = p->begin(); i != p->end(); ++i)
- {
- if ((*i).fedBinding.hasLocal()) {
- propagateFedOp( (*i).binding->key, string(), fedOpBind, string());
- }
- }
- }
- }
- routeIVE();
- if (propagate) {
- FieldTable * prop_args = (extra_args.count() != 0 ? &extra_args : 0);
- propagateFedOp(bindingKey, fedTags, fedOp, fedOrigin, prop_args);
- }
-
- return true;
-}
-
-bool HeadersExchange::unbind(Queue::shared_ptr queue, const string& bindingKey, const FieldTable *args){
- bool propagate = false;
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- {
- Mutex::ScopedLock l(lock);
-
- FedUnbindModifier modifier(queue->getName(), fedOrigin);
- MatchKey match_key(queue, bindingKey);
- bindings.modify_if(match_key, modifier);
- propagate = modifier.shouldPropagate;
- if (modifier.shouldUnbind) {
- if (bindings.remove_if(match_key)) {
- if (mgmtExchange != 0) {
- mgmtExchange->dec_bindingCount();
- }
- } else {
- return false;
- }
- }
- }
-
- if (propagate) {
- propagateFedOp(bindingKey, string(), fedOpUnbind, string());
- }
- return true;
-}
-
-
-void HeadersExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* args)
-{
- if (!args) {
- //can't match if there were no headers passed in
- if (mgmtExchange != 0) {
- mgmtExchange->inc_msgReceives();
- mgmtExchange->inc_byteReceives(msg.contentSize());
- mgmtExchange->inc_msgDrops();
- mgmtExchange->inc_byteDrops(msg.contentSize());
- }
- return;
- }
-
- PreRoute pr(msg, this);
-
- BindingList b(new std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> >);
- Bindings::ConstPtr p = bindings.snapshot();
- if (p.get()) {
- for (std::vector<BoundKey>::const_iterator i = p->begin(); i != p->end(); ++i) {
- if (match((*i).binding->args, *args)) {
- b->push_back((*i).binding);
- }
- }
- }
- doRoute(msg, b);
-}
-
-
-bool HeadersExchange::isBound(Queue::shared_ptr queue, const string* const, const FieldTable* const args)
-{
- Bindings::ConstPtr p = bindings.snapshot();
- if (p.get()){
- for (std::vector<BoundKey>::const_iterator i = p->begin(); i != p->end(); ++i) {
- if ( (!args || equal((*i).binding->args, *args)) && (!queue || (*i).binding->queue == queue)) {
- return true;
- }
- }
- }
- return false;
-}
-
-void HeadersExchange::getNonFedArgs(const FieldTable* args, FieldTable& nonFedArgs)
-{
- if (!args)
- {
- return;
- }
-
- for (qpid::framing::FieldTable::ValueMap::const_iterator i=args->begin(); i != args->end(); ++i)
- {
- const string & name(i->first);
- if (name == qpidFedOp ||
- name == qpidFedTags ||
- name == qpidFedOrigin)
- {
- continue;
- }
- nonFedArgs.insert((*i));
- }
-}
-
-HeadersExchange::~HeadersExchange() {}
-
-const std::string HeadersExchange::typeName("headers");
-
-namespace
-{
-
- bool match_values(const FieldValue& bind, const FieldValue& msg) {
- return bind.getType() == 0xf0 || bind == msg;
- }
-
-}
-
-
-bool HeadersExchange::match(const FieldTable& bind, const FieldTable& msg) {
- typedef FieldTable::ValueMap Map;
- std::string what = getMatch(&bind);
- if (what == all) {
- for (Map::const_iterator i = bind.begin();
- i != bind.end();
- ++i)
- {
- if (i->first != x_match)
- {
- Map::const_iterator j = msg.find(i->first);
- if (j == msg.end()) return false;
- if (!match_values(*(i->second), *(j->second))) return false;
- }
- }
- return true;
- } else if (what == any) {
- for (Map::const_iterator i = bind.begin();
- i != bind.end();
- ++i)
- {
- if (i->first != x_match)
- {
- Map::const_iterator j = msg.find(i->first);
- if (j != msg.end()) {
- if (match_values(*(i->second), *(j->second))) return true;
- }
- }
- }
- return false;
- } else {
- return false;
- }
-}
-
-bool HeadersExchange::equal(const FieldTable& a, const FieldTable& b) {
- typedef FieldTable::ValueMap Map;
- for (Map::const_iterator i = a.begin();
- i != a.end();
- ++i)
- {
- Map::const_iterator j = b.find(i->first);
- if (j == b.end()) return false;
- if (!match_values(*(i->second), *(j->second))) return false;
- }
- return true;
-}
-
-//---------
-HeadersExchange::MatchArgs::MatchArgs(Queue::shared_ptr q, const qpid::framing::FieldTable* a) : queue(q), args(a) {}
-
-bool HeadersExchange::MatchArgs::operator()(BoundKey & bk)
-{
- return bk.binding->queue == queue && bk.binding->args == *args;
-}
-
-//---------
-HeadersExchange::MatchKey::MatchKey(Queue::shared_ptr q, const std::string& k) : queue(q), key(k) {}
-
-bool HeadersExchange::MatchKey::operator()(BoundKey & bk)
-{
- return bk.binding->queue == queue && bk.binding->key == key;
-}
-
-//----------
-HeadersExchange::FedUnbindModifier::FedUnbindModifier(const string& queueName, const string& origin) : queueName(queueName), fedOrigin(origin), shouldUnbind(false), shouldPropagate(false) {}
-HeadersExchange::FedUnbindModifier::FedUnbindModifier() : shouldUnbind(false), shouldPropagate(false) {}
-
-bool HeadersExchange::FedUnbindModifier::operator()(BoundKey & bk)
-{
- shouldPropagate = bk.fedBinding.delOrigin(queueName, fedOrigin);
- if (bk.fedBinding.countFedBindings(queueName) == 0)
- {
- shouldUnbind = true;
- }
- return true;
-}
-
diff --git a/cpp/src/qpid/broker/HeadersExchange.h b/cpp/src/qpid/broker/HeadersExchange.h
deleted file mode 100644
index 3b939d6851..0000000000
--- a/cpp/src/qpid/broker/HeadersExchange.h
+++ /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.
- *
- */
-#ifndef _HeadersExchange_
-#define _HeadersExchange_
-
-#include <vector>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/CopyOnWriteArray.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/broker/Queue.h"
-
-namespace qpid {
-namespace broker {
-
-
-class HeadersExchange : public virtual Exchange {
-
- struct BoundKey
- {
- Binding::shared_ptr binding;
- FedBinding fedBinding;
- BoundKey(Binding::shared_ptr binding_) : binding(binding_) {}
- };
-
- struct MatchArgs
- {
- const Queue::shared_ptr queue;
- const qpid::framing::FieldTable* args;
- MatchArgs(Queue::shared_ptr q, const qpid::framing::FieldTable* a);
- bool operator()(BoundKey & bk);
- };
-
- struct MatchKey
- {
- const Queue::shared_ptr queue;
- const std::string& key;
- MatchKey(Queue::shared_ptr q, const std::string& k);
- bool operator()(BoundKey & bk);
- };
-
- struct FedUnbindModifier
- {
- std::string queueName;
- std::string fedOrigin;
- bool shouldUnbind;
- bool shouldPropagate;
- FedUnbindModifier();
- FedUnbindModifier(const std::string& queueName, const std::string& origin);
- bool operator()(BoundKey & bk);
- };
-
- typedef qpid::sys::CopyOnWriteArray<BoundKey> Bindings;
-
- Bindings bindings;
- qpid::sys::Mutex lock;
-
- static std::string getMatch(const framing::FieldTable* args);
-
- protected:
- void getNonFedArgs(const framing::FieldTable* args,
- framing::FieldTable& nonFedArgs);
-
- public:
- static const std::string typeName;
-
- QPID_BROKER_EXTERN HeadersExchange(const std::string& name,
- management::Manageable* parent = 0, Broker* broker = 0);
- QPID_BROKER_EXTERN HeadersExchange(const std::string& _name,
- bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0, Broker* broker = 0);
-
- virtual std::string getType() const { return typeName; }
-
- QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
-
- virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
-
- QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
-
- QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
- const std::string* const routingKey,
- const qpid::framing::FieldTable* const args);
-
- QPID_BROKER_EXTERN virtual ~HeadersExchange();
-
- virtual bool supportsDynamicBinding() { return true; }
-
- static QPID_BROKER_EXTERN bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
- static bool equal(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
-};
-
-
-
-}
-}
-
-#endif
diff --git a/cpp/src/qpid/broker/LegacyLVQ.cpp b/cpp/src/qpid/broker/LegacyLVQ.cpp
deleted file mode 100644
index a811a86492..0000000000
--- a/cpp/src/qpid/broker/LegacyLVQ.cpp
+++ /dev/null
@@ -1,116 +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.
- *
- */
-#include "qpid/broker/LegacyLVQ.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/QueuedMessage.h"
-
-namespace qpid {
-namespace broker {
-
-LegacyLVQ::LegacyLVQ(const std::string& k, bool b, Broker* br) : MessageMap(k), noBrowse(b), broker(br) {}
-
-void LegacyLVQ::setNoBrowse(bool b)
-{
- noBrowse = b;
-}
-
-bool LegacyLVQ::remove(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- Ordering::iterator i = messages.find(position);
- if (i != messages.end() && i->second.payload == message.payload) {
- message = i->second;
- erase(i);
- return true;
- } else {
- return false;
- }
-}
-
-bool LegacyLVQ::next(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- if (MessageMap::next(position, message)) {
- if (!noBrowse) index.erase(getKey(message));
- return true;
- } else {
- return false;
- }
-}
-
-bool LegacyLVQ::push(const QueuedMessage& added, QueuedMessage& removed)
-{
- //Hack to disable LVQ behaviour on cluster update:
- if (broker && broker->isClusterUpdatee()) {
- messages[added.position] = added;
- return false;
- } else {
- return MessageMap::push(added, removed);
- }
-}
-
-const QueuedMessage& LegacyLVQ::replace(const QueuedMessage& original, const QueuedMessage& update)
-{
- //add the new message into the original position of the replaced message
- Ordering::iterator i = messages.find(original.position);
- i->second = update;
- i->second.position = original.position;
- return i->second;
-}
-
-void LegacyLVQ::removeIf(Predicate p)
-{
- //Note: This method is currently called periodically on the timer
- //thread to expire messages. In a clustered broker this means that
- //the purging does not occur on the cluster event dispatch thread
- //and consequently that is not totally ordered w.r.t other events
- //(including publication of messages). The cluster does ensure
- //that the actual expiration of messages (as distinct from the
- //removing of those expired messages from the queue) *is*
- //consistently ordered w.r.t. cluster events. This means that
- //delivery of messages is in general consistent across the cluster
- //inspite of any non-determinism in the triggering of a
- //purge. However at present purging a last value queue (of the
- //legacy sort) could potentially cause inconsistencies in the
- //cluster (as the order w.r.t publications can affect the order in
- //which messages appear in the queue). Consequently periodic
- //purging of an LVQ is not enabled if the broker is clustered
- //(expired messages will be removed on delivery and consolidated
- //by key as part of normal LVQ operation).
-
- //TODO: Is there a neater way to check whether broker is
- //clustered? Here we assume that if the clustered timer is the
- //same as the regular timer, we are not clustered:
- if (!broker || &(broker->getClusterTimer()) == &(broker->getTimer()))
- MessageMap::removeIf(p);
-}
-
-std::auto_ptr<Messages> LegacyLVQ::updateOrReplace(std::auto_ptr<Messages> current,
- const std::string& key, bool noBrowse, Broker* broker)
-{
- LegacyLVQ* lvq = dynamic_cast<LegacyLVQ*>(current.get());
- if (lvq) {
- lvq->setNoBrowse(noBrowse);
- return current;
- } else {
- return std::auto_ptr<Messages>(new LegacyLVQ(key, noBrowse, broker));
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/LegacyLVQ.h b/cpp/src/qpid/broker/LegacyLVQ.h
deleted file mode 100644
index dd0fd7aaec..0000000000
--- a/cpp/src/qpid/broker/LegacyLVQ.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef QPID_BROKER_LEGACYLVQ_H
-#define QPID_BROKER_LEGACYLVQ_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/MessageMap.h"
-#include <memory>
-
-namespace qpid {
-namespace broker {
-class Broker;
-
-/**
- * This class encapsulates the behaviour of the old style LVQ where a
- * message replacing another messages for the given key will use the
- * position in the queue of the previous message. This however causes
- * problems for browsing. Either browsers stop the coalescing of
- * messages by key (default) or they may mis updates (if the no-browse
- * option is specified).
- */
-class LegacyLVQ : public MessageMap
-{
- public:
- LegacyLVQ(const std::string& key, bool noBrowse = false, Broker* broker = 0);
- bool remove(const framing::SequenceNumber&, QueuedMessage&);
- bool next(const framing::SequenceNumber&, QueuedMessage&);
- bool push(const QueuedMessage& added, QueuedMessage& removed);
- void removeIf(Predicate);
- void setNoBrowse(bool);
- static std::auto_ptr<Messages> updateOrReplace(std::auto_ptr<Messages> current,
- const std::string& key, bool noBrowse,
- Broker* broker);
- protected:
- bool noBrowse;
- Broker* broker;
-
- const QueuedMessage& replace(const QueuedMessage&, const QueuedMessage&);
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_LEGACYLVQ_H*/
diff --git a/cpp/src/qpid/broker/Link.cpp b/cpp/src/qpid/broker/Link.cpp
deleted file mode 100644
index 91861ade3f..0000000000
--- a/cpp/src/qpid/broker/Link.cpp
+++ /dev/null
@@ -1,474 +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.
- *
- */
-
-#include "qpid/broker/Link.h"
-#include "qpid/broker/LinkRegistry.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/Connection.h"
-#include "qmf/org/apache/qpid/broker/EventBrokerLinkUp.h"
-#include "qmf/org/apache/qpid/broker/EventBrokerLinkDown.h"
-#include "boost/bind.hpp"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/enum.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/broker/AclModule.h"
-
-using namespace qpid::broker;
-using qpid::framing::Buffer;
-using qpid::framing::FieldTable;
-using qpid::framing::UnauthorizedAccessException;
-using qpid::framing::connection::CLOSE_CODE_CONNECTION_FORCED;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
-using std::stringstream;
-using std::string;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-Link::Link(LinkRegistry* _links,
- MessageStore* _store,
- string& _host,
- uint16_t _port,
- string& _transport,
- bool _durable,
- string& _authMechanism,
- string& _username,
- string& _password,
- Broker* _broker,
- Manageable* parent)
- : links(_links), store(_store), host(_host), port(_port),
- transport(_transport),
- durable(_durable),
- authMechanism(_authMechanism), username(_username), password(_password),
- persistenceId(0), mgmtObject(0), broker(_broker), state(0),
- visitCount(0),
- currentInterval(1),
- closing(false),
- updateUrls(false),
- channelCounter(1),
- connection(0),
- agent(0)
-{
- if (parent != 0 && broker != 0)
- {
- agent = broker->getManagementAgent();
- if (agent != 0)
- {
- mgmtObject = new _qmf::Link(agent, this, parent, _host, _port, _transport, _durable);
- agent->addObject(mgmtObject, 0, durable);
- }
- }
- setStateLH(STATE_WAITING);
-}
-
-Link::~Link ()
-{
- if (state == STATE_OPERATIONAL && connection != 0)
- connection->close(CLOSE_CODE_CONNECTION_FORCED, "closed by management");
-
- if (mgmtObject != 0)
- mgmtObject->resourceDestroy ();
-}
-
-void Link::setStateLH (int newState)
-{
- if (newState == state)
- return;
-
- state = newState;
-
- if (hideManagement())
- return;
-
- switch (state)
- {
- case STATE_WAITING : mgmtObject->set_state("Waiting"); break;
- case STATE_CONNECTING : mgmtObject->set_state("Connecting"); break;
- case STATE_OPERATIONAL : mgmtObject->set_state("Operational"); break;
- case STATE_FAILED : mgmtObject->set_state("Failed"); break;
- case STATE_CLOSED : mgmtObject->set_state("Closed"); break;
- case STATE_PASSIVE : mgmtObject->set_state("Passive"); break;
- }
-}
-
-void Link::startConnectionLH ()
-{
- try {
- // Set the state before calling connect. It is possible that connect
- // will fail synchronously and call Link::closed before returning.
- setStateLH(STATE_CONNECTING);
- broker->connect (host, port, transport,
- boost::bind (&Link::closed, this, _1, _2));
- QPID_LOG (debug, "Inter-broker link connecting to " << host << ":" << port);
- } catch(std::exception& e) {
- setStateLH(STATE_WAITING);
- if (!hideManagement())
- mgmtObject->set_lastError (e.what());
- }
-}
-
-void Link::established ()
-{
- stringstream addr;
- addr << host << ":" << port;
- QPID_LOG (info, "Inter-broker link established to " << addr.str());
-
- if (!hideManagement() && agent)
- agent->raiseEvent(_qmf::EventBrokerLinkUp(addr.str()));
-
- {
- Mutex::ScopedLock mutex(lock);
- setStateLH(STATE_OPERATIONAL);
- currentInterval = 1;
- visitCount = 0;
- if (closing)
- destroy();
- }
-}
-
-void Link::closed (int, std::string text)
-{
- Mutex::ScopedLock mutex(lock);
- QPID_LOG (info, "Inter-broker link disconnected from " << host << ":" << port << " " << text);
-
- connection = 0;
-
- if (state == STATE_OPERATIONAL) {
- stringstream addr;
- addr << host << ":" << port;
- QPID_LOG (warning, "Inter-broker link disconnected from " << addr.str());
- if (!hideManagement() && agent)
- agent->raiseEvent(_qmf::EventBrokerLinkDown(addr.str()));
- }
-
- for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- (*i)->closed();
- created.push_back(*i);
- }
- active.clear();
-
- if (state != STATE_FAILED)
- {
- setStateLH(STATE_WAITING);
- if (!hideManagement())
- mgmtObject->set_lastError (text);
- }
-
- if (closing)
- destroy();
-}
-
-void Link::destroy ()
-{
- Bridges toDelete;
- {
- Mutex::ScopedLock mutex(lock);
-
- QPID_LOG (info, "Inter-broker link to " << host << ":" << port << " removed by management");
- if (connection)
- connection->close(CLOSE_CODE_CONNECTION_FORCED, "closed by management");
-
- setStateLH(STATE_CLOSED);
-
- // Move the bridges to be deleted into a local vector so there is no
- // corruption of the iterator caused by bridge deletion.
- for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- (*i)->closed();
- toDelete.push_back(*i);
- }
- active.clear();
-
- for (Bridges::iterator i = created.begin(); i != created.end(); i++)
- toDelete.push_back(*i);
- created.clear();
- }
- // Now delete all bridges on this link (don't hold the lock for this).
- for (Bridges::iterator i = toDelete.begin(); i != toDelete.end(); i++)
- (*i)->destroy();
- toDelete.clear();
- links->destroy (host, port);
-}
-
-void Link::add(Bridge::shared_ptr bridge)
-{
- Mutex::ScopedLock mutex(lock);
- created.push_back (bridge);
-}
-
-void Link::cancel(Bridge::shared_ptr bridge)
-{
- {
- Mutex::ScopedLock mutex(lock);
-
- for (Bridges::iterator i = created.begin(); i != created.end(); i++) {
- if ((*i).get() == bridge.get()) {
- created.erase(i);
- break;
- }
- }
- for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- if ((*i).get() == bridge.get()) {
- cancellations.push_back(bridge);
- bridge->closed();
- active.erase(i);
- break;
- }
- }
- }
- if (!cancellations.empty()) {
- connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
- }
-}
-
-void Link::ioThreadProcessing()
-{
- Mutex::ScopedLock mutex(lock);
-
- if (state != STATE_OPERATIONAL)
- return;
- QPID_LOG(debug, "Link::ioThreadProcessing()");
-
- //process any pending creates and/or cancellations
- if (!created.empty()) {
- for (Bridges::iterator i = created.begin(); i != created.end(); ++i) {
- active.push_back(*i);
- (*i)->create(*connection);
- }
- created.clear();
- }
- if (!cancellations.empty()) {
- for (Bridges::iterator i = cancellations.begin(); i != cancellations.end(); ++i) {
- (*i)->cancel(*connection);
- }
- cancellations.clear();
- }
-}
-
-void Link::setConnection(Connection* c)
-{
- Mutex::ScopedLock mutex(lock);
- connection = c;
- updateUrls = true;
-}
-
-void Link::maintenanceVisit ()
-{
- Mutex::ScopedLock mutex(lock);
-
- if (connection && updateUrls) {
- urls.reset(connection->getKnownHosts());
- QPID_LOG(debug, "Known hosts for peer of inter-broker link: " << urls);
- updateUrls = false;
- }
-
- if (state == STATE_WAITING)
- {
- visitCount++;
- if (visitCount >= currentInterval)
- {
- visitCount = 0;
- //switch host and port to next in url list if possible
- if (!tryFailover()) {
- currentInterval *= 2;
- if (currentInterval > MAX_INTERVAL)
- currentInterval = MAX_INTERVAL;
- startConnectionLH();
- }
- }
- }
- else if (state == STATE_OPERATIONAL && (!created.empty() || !cancellations.empty()) && connection != 0)
- connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
-}
-
-void Link::reconnect(const qpid::Address& a)
-{
- Mutex::ScopedLock mutex(lock);
- host = a.host;
- port = a.port;
- transport = a.protocol;
- startConnectionLH();
- if (!hideManagement()) {
- stringstream errorString;
- errorString << "Failed over to " << a;
- mgmtObject->set_lastError(errorString.str());
- }
-}
-
-bool Link::tryFailover()
-{
- Address next;
- if (urls.next(next) &&
- (next.host != host || next.port != port || next.protocol != transport)) {
- links->changeAddress(Address(transport, host, port), next);
- QPID_LOG(debug, "Link failing over to " << host << ":" << port);
- return true;
- } else {
- return false;
- }
-}
-
-// Management updates for a linke are inconsistent in a cluster, so they are
-// suppressed.
-bool Link::hideManagement() const {
- return !mgmtObject || ( broker && broker->isInCluster());
-}
-
-uint Link::nextChannel()
-{
- Mutex::ScopedLock mutex(lock);
-
- return channelCounter++;
-}
-
-void Link::notifyConnectionForced(const string text)
-{
- Mutex::ScopedLock mutex(lock);
-
- setStateLH(STATE_FAILED);
- if (!hideManagement())
- mgmtObject->set_lastError(text);
-}
-
-void Link::setPersistenceId(uint64_t id) const
-{
- persistenceId = id;
-}
-
-const string& Link::getName() const
-{
- return host;
-}
-
-Link::shared_ptr Link::decode(LinkRegistry& links, Buffer& buffer)
-{
- string host;
- uint16_t port;
- string transport;
- string authMechanism;
- string username;
- string password;
-
- buffer.getShortString(host);
- port = buffer.getShort();
- buffer.getShortString(transport);
- bool durable(buffer.getOctet());
- buffer.getShortString(authMechanism);
- buffer.getShortString(username);
- buffer.getShortString(password);
-
- return links.declare(host, port, transport, durable, authMechanism, username, password).first;
-}
-
-void Link::encode(Buffer& buffer) const
-{
- buffer.putShortString(string("link"));
- buffer.putShortString(host);
- buffer.putShort(port);
- buffer.putShortString(transport);
- buffer.putOctet(durable ? 1 : 0);
- buffer.putShortString(authMechanism);
- buffer.putShortString(username);
- buffer.putShortString(password);
-}
-
-uint32_t Link::encodedSize() const
-{
- return host.size() + 1 // short-string (host)
- + 5 // short-string ("link")
- + 2 // port
- + transport.size() + 1 // short-string(transport)
- + 1 // durable
- + authMechanism.size() + 1
- + username.size() + 1
- + password.size() + 1;
-}
-
-ManagementObject* Link::GetManagementObject (void) const
-{
- return (ManagementObject*) mgmtObject;
-}
-
-Manageable::status_t Link::ManagementMethod (uint32_t op, Args& args, string& text)
-{
- switch (op)
- {
- case _qmf::Link::METHOD_CLOSE :
- if (!closing) {
- closing = true;
- if (state != STATE_CONNECTING && connection) {
- //connection can only be closed on the connections own IO processing thread
- connection->requestIOProcessing(boost::bind(&Link::destroy, this));
- }
- }
- return Manageable::STATUS_OK;
-
- case _qmf::Link::METHOD_BRIDGE :
- _qmf::ArgsLinkBridge& iargs = (_qmf::ArgsLinkBridge&) args;
- QPID_LOG(debug, "Link::bridge() request received");
-
- // Durable bridges are only valid on durable links
- if (iargs.i_durable && !durable) {
- text = "Can't create a durable route on a non-durable link";
- return Manageable::STATUS_USER;
- }
-
- if (iargs.i_dynamic) {
- Exchange::shared_ptr exchange = getBroker()->getExchanges().get(iargs.i_src);
- if (exchange.get() == 0) {
- text = "Exchange not found";
- return Manageable::STATUS_USER;
- }
- if (!exchange->supportsDynamicBinding()) {
- text = "Exchange type does not support dynamic routing";
- return Manageable::STATUS_USER;
- }
- }
-
- std::pair<Bridge::shared_ptr, bool> result =
- links->declare (host, port, iargs.i_durable, iargs.i_src,
- iargs.i_dest, iargs.i_key, iargs.i_srcIsQueue,
- iargs.i_srcIsLocal, iargs.i_tag, iargs.i_excludes,
- iargs.i_dynamic, iargs.i_sync);
-
- if (result.second && iargs.i_durable)
- store->create(*result.first);
-
- return Manageable::STATUS_OK;
- }
-
- return Manageable::STATUS_UNKNOWN_METHOD;
-}
-
-void Link::setPassive(bool passive)
-{
- Mutex::ScopedLock mutex(lock);
- if (passive) {
- setStateLH(STATE_PASSIVE);
- } else {
- if (state == STATE_PASSIVE) {
- setStateLH(STATE_WAITING);
- } else {
- QPID_LOG(warning, "Ignoring attempt to activate non-passive link");
- }
- }
-}
diff --git a/cpp/src/qpid/broker/Link.h b/cpp/src/qpid/broker/Link.h
deleted file mode 100644
index 4badd8b3a1..0000000000
--- a/cpp/src/qpid/broker/Link.h
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef _broker_Link_h
-#define _broker_Link_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/shared_ptr.hpp>
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/PersistableConfig.h"
-#include "qpid/broker/Bridge.h"
-#include "qpid/broker/RetryList.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/management/Manageable.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qmf/org/apache/qpid/broker/Link.h"
-#include <boost/ptr_container/ptr_vector.hpp>
-
-namespace qpid {
- namespace broker {
-
- class LinkRegistry;
- class Broker;
- class Connection;
-
- class Link : public PersistableConfig, public management::Manageable {
- private:
- sys::Mutex lock;
- LinkRegistry* links;
- MessageStore* store;
- std::string host;
- uint16_t port;
- std::string transport;
- bool durable;
- std::string authMechanism;
- std::string username;
- std::string password;
- mutable uint64_t persistenceId;
- qmf::org::apache::qpid::broker::Link* mgmtObject;
- Broker* broker;
- int state;
- uint32_t visitCount;
- uint32_t currentInterval;
- bool closing;
- RetryList urls;
- bool updateUrls;
-
- typedef std::vector<Bridge::shared_ptr> Bridges;
- Bridges created; // Bridges pending creation
- Bridges active; // Bridges active
- Bridges cancellations; // Bridges pending cancellation
- uint channelCounter;
- Connection* connection;
- management::ManagementAgent* agent;
-
- static const int STATE_WAITING = 1;
- static const int STATE_CONNECTING = 2;
- static const int STATE_OPERATIONAL = 3;
- static const int STATE_FAILED = 4;
- static const int STATE_CLOSED = 5;
- static const int STATE_PASSIVE = 6;
-
- static const uint32_t MAX_INTERVAL = 32;
-
- void setStateLH (int newState);
- void startConnectionLH(); // Start the IO Connection
- void destroy(); // Called when mgmt deletes this link
- void ioThreadProcessing(); // Called on connection's IO thread by request
- bool tryFailover(); // Called during maintenance visit
- bool hideManagement() const;
-
- public:
- typedef boost::shared_ptr<Link> shared_ptr;
-
- Link(LinkRegistry* links,
- MessageStore* store,
- std::string& host,
- uint16_t port,
- std::string& transport,
- bool durable,
- std::string& authMechanism,
- std::string& username,
- std::string& password,
- Broker* broker,
- management::Manageable* parent = 0);
- virtual ~Link();
-
- std::string getHost() { return host; }
- uint16_t getPort() { return port; }
- bool isDurable() { return durable; }
- void maintenanceVisit ();
- uint nextChannel();
- void add(Bridge::shared_ptr);
- void cancel(Bridge::shared_ptr);
-
- void established(); // Called when connection is created
- void closed(int, std::string); // Called when connection goes away
- void setConnection(Connection*); // Set pointer to the AMQP Connection
- void reconnect(const Address&); //called by LinkRegistry
-
- std::string getAuthMechanism() { return authMechanism; }
- std::string getUsername() { return username; }
- std::string getPassword() { return password; }
- Broker* getBroker() { return broker; }
-
- void notifyConnectionForced(const std::string text);
- void setPassive(bool p);
-
- // PersistableConfig:
- void setPersistenceId(uint64_t id) const;
- uint64_t getPersistenceId() const { return persistenceId; }
- uint32_t encodedSize() const;
- void encode(framing::Buffer& buffer) const;
- const std::string& getName() const;
-
- static Link::shared_ptr decode(LinkRegistry& links, framing::Buffer& buffer);
-
- // Manageable entry points
- management::ManagementObject* GetManagementObject(void) const;
- management::Manageable::status_t ManagementMethod(uint32_t, management::Args&, std::string&);
-
- };
- }
-}
-
-
-#endif /*!_broker_Link.cpp_h*/
diff --git a/cpp/src/qpid/broker/LinkRegistry.cpp b/cpp/src/qpid/broker/LinkRegistry.cpp
deleted file mode 100644
index e9885f5462..0000000000
--- a/cpp/src/qpid/broker/LinkRegistry.cpp
+++ /dev/null
@@ -1,399 +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.
- *
- */
-#include "qpid/broker/LinkRegistry.h"
-#include "qpid/broker/Link.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/log/Statement.h"
-#include <iostream>
-#include <boost/format.hpp>
-
-using namespace qpid::broker;
-using namespace qpid::sys;
-using std::string;
-using std::pair;
-using std::stringstream;
-using boost::intrusive_ptr;
-using boost::format;
-using boost::str;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-#define LINK_MAINT_INTERVAL 2
-
-// TODO: This constructor is only used by the store unit tests -
-// That probably indicates that LinkRegistry isn't correctly
-// factored: The persistence element and maintenance element
-// should be factored separately
-LinkRegistry::LinkRegistry () :
- broker(0), timer(0),
- parent(0), store(0), passive(false), passiveChanged(false),
- realm("")
-{
-}
-
-LinkRegistry::LinkRegistry (Broker* _broker) :
- broker(_broker), timer(&broker->getTimer()),
- maintenanceTask(new Periodic(*this)),
- parent(0), store(0), passive(false), passiveChanged(false),
- realm(broker->getOptions().realm)
-{
- timer->add(maintenanceTask);
-}
-
-LinkRegistry::~LinkRegistry()
-{
- // This test is only necessary if the default constructor above is present
- if (maintenanceTask)
- maintenanceTask->cancel();
-}
-
-LinkRegistry::Periodic::Periodic (LinkRegistry& _links) :
- TimerTask (Duration (LINK_MAINT_INTERVAL * TIME_SEC),"LinkRegistry"), links(_links) {}
-
-void LinkRegistry::Periodic::fire ()
-{
- links.periodicMaintenance ();
- setupNextFire();
- links.timer->add(this);
-}
-
-void LinkRegistry::periodicMaintenance ()
-{
- Mutex::ScopedLock locker(lock);
-
- linksToDestroy.clear();
- bridgesToDestroy.clear();
- if (passiveChanged) {
- if (passive) { QPID_LOG(info, "Passivating links"); }
- else { QPID_LOG(info, "Activating links"); }
- for (LinkMap::iterator i = links.begin(); i != links.end(); i++) {
- i->second->setPassive(passive);
- }
- passiveChanged = false;
- }
- for (LinkMap::iterator i = links.begin(); i != links.end(); i++)
- i->second->maintenanceVisit();
- //now process any requests for re-addressing
- for (AddressMap::iterator i = reMappings.begin(); i != reMappings.end(); i++)
- updateAddress(i->first, i->second);
- reMappings.clear();
-}
-
-void LinkRegistry::changeAddress(const qpid::Address& oldAddress, const qpid::Address& newAddress)
-{
- //done on periodic maintenance thread; hold changes in separate
- //map to avoid modifying the link map that is iterated over
- reMappings[createKey(oldAddress)] = newAddress;
-}
-
-bool LinkRegistry::updateAddress(const std::string& oldKey, const qpid::Address& newAddress)
-{
- std::string newKey = createKey(newAddress);
- if (links.find(newKey) != links.end()) {
- QPID_LOG(error, "Attempted to update key from " << oldKey << " to " << newKey << " which is already in use");
- return false;
- } else {
- LinkMap::iterator i = links.find(oldKey);
- if (i == links.end()) {
- QPID_LOG(error, "Attempted to update key from " << oldKey << " which does not exist, to " << newKey);
- return false;
- } else {
- links[newKey] = i->second;
- i->second->reconnect(newAddress);
- links.erase(oldKey);
- QPID_LOG(info, "Updated link key from " << oldKey << " to " << newKey);
- return true;
- }
- }
-}
-
-pair<Link::shared_ptr, bool> LinkRegistry::declare(string& host,
- uint16_t port,
- string& transport,
- bool durable,
- string& authMechanism,
- string& username,
- string& password)
-
-{
- Mutex::ScopedLock locker(lock);
- string key = createKey(host, port);
-
- LinkMap::iterator i = links.find(key);
- if (i == links.end())
- {
- Link::shared_ptr link;
-
- link = Link::shared_ptr (new Link (this, store, host, port, transport, durable,
- authMechanism, username, password,
- broker, parent));
- if (passive) link->setPassive(true);
- links[key] = link;
- return std::pair<Link::shared_ptr, bool>(link, true);
- }
- return std::pair<Link::shared_ptr, bool>(i->second, false);
-}
-
-pair<Bridge::shared_ptr, bool> LinkRegistry::declare(std::string& host,
- uint16_t port,
- bool durable,
- std::string& src,
- std::string& dest,
- std::string& key,
- bool isQueue,
- bool isLocal,
- std::string& tag,
- std::string& excludes,
- bool dynamic,
- uint16_t sync)
-{
- Mutex::ScopedLock locker(lock);
- QPID_LOG(debug, "Bridge declared " << host << ": " << port << " from " << src << " to " << dest << " (" << key << ")");
-
- string linkKey = createKey(host, port);
- stringstream keystream;
- keystream << linkKey << "!" << src << "!" << dest << "!" << key;
- string bridgeKey = keystream.str();
-
- LinkMap::iterator l = links.find(linkKey);
- if (l == links.end())
- return pair<Bridge::shared_ptr, bool>(Bridge::shared_ptr(), false);
-
- BridgeMap::iterator b = bridges.find(bridgeKey);
- if (b == bridges.end())
- {
- _qmf::ArgsLinkBridge args;
- Bridge::shared_ptr bridge;
-
- args.i_durable = durable;
- args.i_src = src;
- args.i_dest = dest;
- args.i_key = key;
- args.i_srcIsQueue = isQueue;
- args.i_srcIsLocal = isLocal;
- args.i_tag = tag;
- args.i_excludes = excludes;
- args.i_dynamic = dynamic;
- args.i_sync = sync;
-
- bridge = Bridge::shared_ptr
- (new Bridge (l->second.get(), l->second->nextChannel(),
- boost::bind(&LinkRegistry::destroy, this,
- host, port, src, dest, key), args));
- bridges[bridgeKey] = bridge;
- l->second->add(bridge);
- return std::pair<Bridge::shared_ptr, bool>(bridge, true);
- }
- return std::pair<Bridge::shared_ptr, bool>(b->second, false);
-}
-
-void LinkRegistry::destroy(const string& host, const uint16_t port)
-{
- Mutex::ScopedLock locker(lock);
- string key = createKey(host, port);
-
- LinkMap::iterator i = links.find(key);
- if (i != links.end())
- {
- if (i->second->isDurable() && store)
- store->destroy(*(i->second));
- linksToDestroy[key] = i->second;
- links.erase(i);
- }
-}
-
-void LinkRegistry::destroy(const std::string& host,
- const uint16_t port,
- const std::string& src,
- const std::string& dest,
- const std::string& key)
-{
- Mutex::ScopedLock locker(lock);
- string linkKey = createKey(host, port);
- stringstream keystream;
- keystream << linkKey << "!" << src << "!" << dest << "!" << key;
- string bridgeKey = keystream.str();
-
- LinkMap::iterator l = links.find(linkKey);
- if (l == links.end())
- return;
-
- BridgeMap::iterator b = bridges.find(bridgeKey);
- if (b == bridges.end())
- return;
-
- l->second->cancel(b->second);
- if (b->second->isDurable())
- store->destroy(*(b->second));
- bridgesToDestroy[bridgeKey] = b->second;
- bridges.erase(b);
-}
-
-void LinkRegistry::setStore (MessageStore* _store)
-{
- store = _store;
-}
-
-MessageStore* LinkRegistry::getStore() const {
- return store;
-}
-
-Link::shared_ptr LinkRegistry::findLink(const std::string& keyOrMgmtId)
-{
- // Convert keyOrMgmtId to a host:port key.
- //
- // TODO aconway 2011-02-01: centralize code that constructs/parses
- // connection management IDs. Currently sys:: protocol factories
- // and IO plugins construct the IDs and LinkRegistry parses them.
- size_t separator = keyOrMgmtId.find('-');
- if (separator == std::string::npos) separator = 0;
- std::string key = keyOrMgmtId.substr(separator+1, std::string::npos);
-
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end()) return l->second;
- else return Link::shared_ptr();
-}
-
-void LinkRegistry::notifyConnection(const std::string& key, Connection* c)
-{
- Link::shared_ptr link = findLink(key);
- if (link) {
- link->established();
- link->setConnection(c);
- c->setUserId(str(format("%1%@%2%") % link->getUsername() % realm));
- }
-}
-
-void LinkRegistry::notifyClosed(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (link) {
- link->closed(0, "Closed by peer");
- }
-}
-
-void LinkRegistry::notifyConnectionForced(const std::string& key, const std::string& text)
-{
- Link::shared_ptr link = findLink(key);
- if (link) {
- link->notifyConnectionForced(text);
- }
-}
-
-std::string LinkRegistry::getAuthMechanism(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (link)
- return link->getAuthMechanism();
- return string("ANONYMOUS");
-}
-
-std::string LinkRegistry::getAuthCredentials(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (!link)
- return string();
-
- string result;
- result += '\0';
- result += link->getUsername();
- result += '\0';
- result += link->getPassword();
-
- return result;
-}
-
-std::string LinkRegistry::getUsername(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (!link)
- return string();
-
- return link->getUsername();
-}
-
-std::string LinkRegistry::getHost(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (!link)
- return string();
-
- return link->getHost();
-}
-
-uint16_t LinkRegistry::getPort(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (!link)
- return 0;
-
- return link->getPort();
-}
-
-std::string LinkRegistry::getPassword(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (!link)
- return string();
-
- return link->getPassword();
-}
-
-std::string LinkRegistry::getAuthIdentity(const std::string& key)
-{
- Link::shared_ptr link = findLink(key);
- if (!link)
- return string();
-
- return link->getUsername();
-}
-
-
-std::string LinkRegistry::createKey(const qpid::Address& a) {
- // TODO aconway 2010-05-11: key should also include protocol/transport to
- // be unique. Requires refactor of LinkRegistry interface.
- return createKey(a.host, a.port);
-}
-
-std::string LinkRegistry::createKey(const std::string& host, uint16_t port) {
- // TODO aconway 2010-05-11: key should also include protocol/transport to
- // be unique. Requires refactor of LinkRegistry interface.
- stringstream keystream;
- keystream << host << ":" << port;
- return keystream.str();
-}
-
-void LinkRegistry::setPassive(bool p)
-{
- Mutex::ScopedLock locker(lock);
- passiveChanged = p != passive;
- passive = p;
- //will activate or passivate links on maintenance visit
-}
-
-void LinkRegistry::eachLink(boost::function<void(boost::shared_ptr<Link>)> f) {
- for (LinkMap::iterator i = links.begin(); i != links.end(); ++i) f(i->second);
-}
-
-void LinkRegistry::eachBridge(boost::function<void(boost::shared_ptr<Bridge>)> f) {
- for (BridgeMap::iterator i = bridges.begin(); i != bridges.end(); ++i) f(i->second);
-}
-
diff --git a/cpp/src/qpid/broker/LinkRegistry.h b/cpp/src/qpid/broker/LinkRegistry.h
deleted file mode 100644
index 4c97e4f9d8..0000000000
--- a/cpp/src/qpid/broker/LinkRegistry.h
+++ /dev/null
@@ -1,163 +0,0 @@
-#ifndef _broker_LinkRegistry_h
-#define _broker_LinkRegistry_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <map>
-#include "qpid/broker/Bridge.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/Address.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Timer.h"
-#include "qpid/management/Manageable.h"
-#include <boost/shared_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/function.hpp>
-
-namespace qpid {
-namespace broker {
-
- class Link;
- class Broker;
- class Connection;
- class LinkRegistry {
-
- // Declare a timer task to manage the establishment of link connections and the
- // re-establishment of lost link connections.
- struct Periodic : public sys::TimerTask
- {
- LinkRegistry& links;
-
- Periodic(LinkRegistry& links);
- virtual ~Periodic() {};
- void fire();
- };
-
- typedef std::map<std::string, boost::shared_ptr<Link> > LinkMap;
- typedef std::map<std::string, Bridge::shared_ptr> BridgeMap;
- typedef std::map<std::string, Address> AddressMap;
-
- LinkMap links;
- LinkMap linksToDestroy;
- BridgeMap bridges;
- BridgeMap bridgesToDestroy;
- AddressMap reMappings;
-
- qpid::sys::Mutex lock;
- Broker* broker;
- sys::Timer* timer;
- boost::intrusive_ptr<qpid::sys::TimerTask> maintenanceTask;
- management::Manageable* parent;
- MessageStore* store;
- bool passive;
- bool passiveChanged;
- std::string realm;
-
- void periodicMaintenance ();
- bool updateAddress(const std::string& oldKey, const Address& newAddress);
- boost::shared_ptr<Link> findLink(const std::string& key);
- static std::string createKey(const Address& address);
- static std::string createKey(const std::string& host, uint16_t port);
-
- public:
- LinkRegistry (); // Only used in store tests
- LinkRegistry (Broker* _broker);
- ~LinkRegistry();
-
- std::pair<boost::shared_ptr<Link>, bool>
- declare(std::string& host,
- uint16_t port,
- std::string& transport,
- bool durable,
- std::string& authMechanism,
- std::string& username,
- std::string& password);
- std::pair<Bridge::shared_ptr, bool>
- declare(std::string& host,
- uint16_t port,
- bool durable,
- std::string& src,
- std::string& dest,
- std::string& key,
- bool isQueue,
- bool isLocal,
- std::string& id,
- std::string& excludes,
- bool dynamic,
- uint16_t sync);
-
- void destroy(const std::string& host, const uint16_t port);
- void destroy(const std::string& host,
- const uint16_t port,
- const std::string& src,
- const std::string& dest,
- const std::string& key);
-
- /**
- * Register the manageable parent for declared queues
- */
- void setParent (management::Manageable* _parent) { parent = _parent; }
-
- /**
- * Set the store to use. May only be called once.
- */
- void setStore (MessageStore*);
-
- /**
- * Return the message store used.
- */
- MessageStore* getStore() const;
-
- void notifyConnection (const std::string& key, Connection* c);
- void notifyClosed (const std::string& key);
- void notifyConnectionForced (const std::string& key, const std::string& text);
- std::string getAuthMechanism (const std::string& key);
- std::string getAuthCredentials (const std::string& key);
- std::string getAuthIdentity (const std::string& key);
- std::string getUsername (const std::string& key);
- std::string getPassword (const std::string& key);
- std::string getHost (const std::string& key);
- uint16_t getPort (const std::string& key);
-
- /**
- * Called by links failing over to new address
- */
- void changeAddress(const Address& oldAddress, const Address& newAddress);
- /**
- * Called to alter passive state. In passive state the links
- * and bridges managed by a link registry will be recorded and
- * updated but links won't actually establish connections and
- * bridges won't therefore pull or push any messages.
- */
- void setPassive(bool);
-
-
- /** Iterate over each link in the registry. Used for cluster updates. */
- void eachLink(boost::function<void(boost::shared_ptr<Link>)> f);
- /** Iterate over each bridge in the registry. Used for cluster updates. */
- void eachBridge(boost::function<void(boost::shared_ptr< Bridge>)> f);
- };
-}
-}
-
-
-#endif /*!_broker_LinkRegistry_h*/
diff --git a/cpp/src/qpid/broker/Message.cpp b/cpp/src/qpid/broker/Message.cpp
deleted file mode 100644
index 763dc55e40..0000000000
--- a/cpp/src/qpid/broker/Message.cpp
+++ /dev/null
@@ -1,452 +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.
- *
- */
-
-#include "qpid/broker/Message.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/ExchangeRegistry.h"
-#include "qpid/broker/ExpiryPolicy.h"
-#include "qpid/StringUtils.h"
-#include "qpid/framing/frame_functors.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/framing/MessageTransferBody.h"
-#include "qpid/framing/SendContent.h"
-#include "qpid/framing/SequenceNumber.h"
-#include "qpid/framing/TypeFilter.h"
-#include "qpid/log/Statement.h"
-
-#include <time.h>
-
-using boost::intrusive_ptr;
-using qpid::sys::AbsTime;
-using qpid::sys::Duration;
-using qpid::sys::TIME_MSEC;
-using qpid::sys::FAR_FUTURE;
-using std::string;
-using namespace qpid::framing;
-
-namespace qpid {
-namespace broker {
-
-TransferAdapter Message::TRANSFER;
-
-Message::Message(const framing::SequenceNumber& id) :
- frames(id), persistenceId(0), redelivered(false), loaded(false),
- staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
- expiration(FAR_FUTURE), dequeueCallback(0),
- inCallback(false), requiredCredit(0), isManagementMessage(false)
-{}
-
-Message::Message(const Message& original) :
- PersistableMessage(), frames(original.frames), persistenceId(0), redelivered(false), loaded(false),
- staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
- expiration(original.expiration), dequeueCallback(0),
- inCallback(false), requiredCredit(0)
-{
- setExpiryPolicy(original.expiryPolicy);
-}
-
-Message::~Message()
-{
- if (expiryPolicy)
- expiryPolicy->forget(*this);
-}
-
-void Message::forcePersistent()
-{
- // only set forced bit if we actually need to force.
- if (! getAdapter().isPersistent(frames) ){
- forcePersistentPolicy = true;
- }
-}
-
-bool Message::isForcedPersistent()
-{
- return forcePersistentPolicy;
-}
-
-std::string Message::getRoutingKey() const
-{
- return getAdapter().getRoutingKey(frames);
-}
-
-std::string Message::getExchangeName() const
-{
- return getAdapter().getExchange(frames);
-}
-
-const boost::shared_ptr<Exchange> Message::getExchange(ExchangeRegistry& registry) const
-{
- if (!exchange) {
- exchange = registry.get(getExchangeName());
- }
- return exchange;
-}
-
-bool Message::isImmediate() const
-{
- return getAdapter().isImmediate(frames);
-}
-
-const FieldTable* Message::getApplicationHeaders() const
-{
- return getAdapter().getApplicationHeaders(frames);
-}
-
-std::string Message::getAppId() const
-{
- return getAdapter().getAppId(frames);
-}
-
-bool Message::isPersistent() const
-{
- return (getAdapter().isPersistent(frames) || forcePersistentPolicy);
-}
-
-bool Message::requiresAccept()
-{
- return getAdapter().requiresAccept(frames);
-}
-
-uint32_t Message::getRequiredCredit()
-{
- sys::Mutex::ScopedLock l(lock);
- if (!requiredCredit) {
- //add up payload for all header and content frames in the frameset
- SumBodySize sum;
- frames.map_if(sum, TypeFilter2<HEADER_BODY, CONTENT_BODY>());
- requiredCredit = sum.getSize();
- }
- return requiredCredit;
-}
-
-void Message::encode(framing::Buffer& buffer) const
-{
- //encode method and header frames
- EncodeFrame f1(buffer);
- frames.map_if(f1, TypeFilter2<METHOD_BODY, HEADER_BODY>());
-
- //then encode the payload of each content frame
- framing::EncodeBody f2(buffer);
- frames.map_if(f2, TypeFilter<CONTENT_BODY>());
-}
-
-void Message::encodeContent(framing::Buffer& buffer) const
-{
- //encode the payload of each content frame
- EncodeBody f2(buffer);
- frames.map_if(f2, TypeFilter<CONTENT_BODY>());
-}
-
-uint32_t Message::encodedSize() const
-{
- return encodedHeaderSize() + encodedContentSize();
-}
-
-uint32_t Message::encodedContentSize() const
-{
- return frames.getContentSize();
-}
-
-uint32_t Message::encodedHeaderSize() const
-{
- //add up the size for all method and header frames in the frameset
- SumFrameSize sum;
- frames.map_if(sum, TypeFilter2<METHOD_BODY, HEADER_BODY>());
- return sum.getSize();
-}
-
-void Message::decodeHeader(framing::Buffer& buffer)
-{
- AMQFrame method;
- method.decode(buffer);
- frames.append(method);
-
- AMQFrame header;
- header.decode(buffer);
- frames.append(header);
-}
-
-void Message::decodeContent(framing::Buffer& buffer)
-{
- if (buffer.available()) {
- //get the data as a string and set that as the content
- //body on a frame then add that frame to the frameset
- AMQFrame frame((AMQContentBody()));
- frame.castBody<AMQContentBody>()->decode(buffer, buffer.available());
- frame.setFirstSegment(false);
- frames.append(frame);
- } else {
- //adjust header flags
- MarkLastSegment f;
- frames.map_if(f, TypeFilter<HEADER_BODY>());
- }
- //mark content loaded
- loaded = true;
-}
-
-// Used for testing only
-void Message::tryReleaseContent()
-{
- if (checkContentReleasable()) {
- releaseContent();
- }
-}
-
-void Message::releaseContent(MessageStore* s)
-{
- //deprecated, use setStore(store); releaseContent(); instead
- if (!store) setStore(s);
- releaseContent();
-}
-
-void Message::releaseContent()
-{
- sys::Mutex::ScopedLock l(lock);
- if (store) {
- if (!getPersistenceId()) {
- intrusive_ptr<PersistableMessage> pmsg(this);
- store->stage(pmsg);
- staged = true;
- }
- //ensure required credit is cached before content frames are released
- getRequiredCredit();
- //remove any content frames from the frameset
- frames.remove(TypeFilter<CONTENT_BODY>());
- setContentReleased();
- }
-}
-
-void Message::destroy()
-{
- if (staged) {
- if (store) {
- store->destroy(*this);
- } else {
- QPID_LOG(error, "Message content was staged but no store is set so it can't be destroyed");
- }
- }
-}
-
-bool Message::getContentFrame(const Queue& queue, AMQFrame& frame, uint16_t maxContentSize, uint64_t offset) const
-{
- intrusive_ptr<const PersistableMessage> pmsg(this);
-
- bool done = false;
- string& data = frame.castBody<AMQContentBody>()->getData();
- store->loadContent(queue, pmsg, data, offset, maxContentSize);
- done = data.size() < maxContentSize;
- frame.setBof(false);
- frame.setEof(true);
- QPID_LOG(debug, "loaded frame" << frame);
- if (offset > 0) {
- frame.setBos(false);
- }
- if (!done) {
- frame.setEos(false);
- } else return false;
- return true;
-}
-
-void Message::sendContent(const Queue& queue, framing::FrameHandler& out, uint16_t maxFrameSize) const
-{
- sys::Mutex::ScopedLock l(lock);
- if (isContentReleased() && !frames.isComplete()) {
- sys::Mutex::ScopedUnlock u(lock);
- uint16_t maxContentSize = maxFrameSize - AMQFrame::frameOverhead();
- bool morecontent = true;
- for (uint64_t offset = 0; morecontent; offset += maxContentSize)
- {
- AMQFrame frame((AMQContentBody()));
- morecontent = getContentFrame(queue, frame, maxContentSize, offset);
- out.handle(frame);
- }
- } else {
- Count c;
- frames.map_if(c, TypeFilter<CONTENT_BODY>());
-
- SendContent f(out, maxFrameSize, c.getCount());
- frames.map_if(f, TypeFilter<CONTENT_BODY>());
- }
-}
-
-void Message::sendHeader(framing::FrameHandler& out, uint16_t /*maxFrameSize*/) const
-{
- sys::Mutex::ScopedLock l(lock);
- Relay f(out);
- frames.map_if(f, TypeFilter<HEADER_BODY>());
-}
-
-// TODO aconway 2007-11-09: Obsolete, remove. Was used to cover over
-// 0-8/0-9 message differences.
-MessageAdapter& Message::getAdapter() const
-{
- if (!adapter) {
- if(frames.isA<MessageTransferBody>()) {
- adapter = &TRANSFER;
- } else {
- const AMQMethodBody* method = frames.getMethod();
- if (!method) throw Exception("Can't adapt message with no method");
- else throw Exception(QPID_MSG("Can't adapt message based on " << *method));
- }
- }
- return *adapter;
-}
-
-uint64_t Message::contentSize() const
-{
- return frames.getContentSize();
-}
-
-bool Message::isContentLoaded() const
-{
- return loaded;
-}
-
-
-namespace
-{
-const std::string X_QPID_TRACE("x-qpid.trace");
-}
-
-bool Message::isExcluded(const std::vector<std::string>& excludes) const
-{
- const FieldTable* headers = getApplicationHeaders();
- if (headers) {
- std::string traceStr = headers->getAsString(X_QPID_TRACE);
- if (traceStr.size()) {
- std::vector<std::string> trace = split(traceStr, ", ");
-
- for (std::vector<std::string>::const_iterator i = excludes.begin(); i != excludes.end(); i++) {
- for (std::vector<std::string>::const_iterator j = trace.begin(); j != trace.end(); j++) {
- if (*i == *j) {
- return true;
- }
- }
- }
- }
- }
- return false;
-}
-
-void Message::addTraceId(const std::string& id)
-{
- sys::Mutex::ScopedLock l(lock);
- if (isA<MessageTransferBody>()) {
- FieldTable& headers = getProperties<MessageProperties>()->getApplicationHeaders();
- std::string trace = headers.getAsString(X_QPID_TRACE);
- if (trace.empty()) {
- headers.setString(X_QPID_TRACE, id);
- } else if (trace.find(id) == std::string::npos) {
- trace += ",";
- trace += id;
- headers.setString(X_QPID_TRACE, trace);
- }
- }
-}
-
-void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
-{
- DeliveryProperties* props = getProperties<DeliveryProperties>();
- if (props->getTtl()) {
- // AMQP requires setting the expiration property to be posix
- // time_t in seconds. TTL is in milliseconds
- if (!props->getExpiration()) {
- //only set expiration in delivery properties if not already set
- time_t now = ::time(0);
- props->setExpiration(now + (props->getTtl()/1000));
- }
- // Use higher resolution time for the internal expiry calculation.
- Duration ttl(std::min(props->getTtl() * TIME_MSEC, (uint64_t) std::numeric_limits<int64_t>::max()));//Prevent overflow
- expiration = AbsTime(AbsTime::now(), ttl);
- setExpiryPolicy(e);
- }
-}
-
-void Message::adjustTtl()
-{
- DeliveryProperties* props = getProperties<DeliveryProperties>();
- if (props->getTtl()) {
- sys::Mutex::ScopedLock l(lock);
- if (expiration < FAR_FUTURE) {
- sys::Duration d(sys::AbsTime::now(), getExpiration());
- props->setTtl(int64_t(d) > 0 ? int64_t(d)/1000000 : 1); // convert from ns to ms; set to 1 if expired
- }
- }
-}
-
-void Message::setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e) {
- expiryPolicy = e;
- if (expiryPolicy)
- expiryPolicy->willExpire(*this);
-}
-
-bool Message::hasExpired()
-{
- return expiryPolicy && expiryPolicy->hasExpired(*this);
-}
-
-namespace {
-struct ScopedSet {
- sys::Monitor& lock;
- bool& flag;
- ScopedSet(sys::Monitor& l, bool& f) : lock(l), flag(f) {
- sys::Monitor::ScopedLock sl(lock);
- flag = true;
- }
- ~ScopedSet(){
- sys::Monitor::ScopedLock sl(lock);
- flag = false;
- lock.notifyAll();
- }
-};
-}
-
-void Message::allDequeuesComplete() {
- ScopedSet ss(callbackLock, inCallback);
- MessageCallback* cb = dequeueCallback;
- if (cb && *cb) (*cb)(intrusive_ptr<Message>(this));
-}
-
-void Message::setDequeueCompleteCallback(MessageCallback& cb) {
- sys::Mutex::ScopedLock l(callbackLock);
- while (inCallback) callbackLock.wait();
- dequeueCallback = &cb;
-}
-
-void Message::resetDequeueCompleteCallback() {
- sys::Mutex::ScopedLock l(callbackLock);
- while (inCallback) callbackLock.wait();
- dequeueCallback = 0;
-}
-
-uint8_t Message::getPriority() const {
- return getAdapter().getPriority(frames);
-}
-
-framing::FieldTable& Message::getOrInsertHeaders()
-{
- return getProperties<MessageProperties>()->getApplicationHeaders();
-}
-
-bool Message::getIsManagementMessage() const { return isManagementMessage; }
-void Message::setIsManagementMessage(bool b) { isManagementMessage = b; }
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/Message.h b/cpp/src/qpid/broker/Message.h
deleted file mode 100644
index d85ee434db..0000000000
--- a/cpp/src/qpid/broker/Message.h
+++ /dev/null
@@ -1,196 +0,0 @@
-#ifndef _broker_Message_h
-#define _broker_Message_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/PersistableMessage.h"
-#include "qpid/broker/MessageAdapter.h"
-#include "qpid/framing/amqp_types.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/sys/Time.h"
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-#include <string>
-#include <vector>
-
-namespace qpid {
-
-namespace framing {
-class FieldTable;
-class SequenceNumber;
-}
-
-namespace broker {
-class ConnectionToken;
-class Exchange;
-class ExchangeRegistry;
-class MessageStore;
-class Queue;
-class ExpiryPolicy;
-
-class Message : public PersistableMessage {
-public:
- typedef boost::function<void (const boost::intrusive_ptr<Message>&)> MessageCallback;
-
- QPID_BROKER_EXTERN Message(const framing::SequenceNumber& id = framing::SequenceNumber());
- QPID_BROKER_EXTERN Message(const Message&);
- QPID_BROKER_EXTERN ~Message();
-
- uint64_t getPersistenceId() const { return persistenceId; }
- void setPersistenceId(uint64_t _persistenceId) const { persistenceId = _persistenceId; }
-
- bool getRedelivered() const { return redelivered; }
- void redeliver() { redelivered = true; }
-
- const ConnectionToken* getPublisher() const { return publisher; }
- void setPublisher(ConnectionToken* p) { publisher = p; }
-
- const framing::SequenceNumber& getCommandId() { return frames.getId(); }
-
- QPID_BROKER_EXTERN uint64_t contentSize() const;
-
- QPID_BROKER_EXTERN std::string getRoutingKey() const;
- const boost::shared_ptr<Exchange> getExchange(ExchangeRegistry&) const;
- QPID_BROKER_EXTERN std::string getExchangeName() const;
- bool isImmediate() const;
- QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const;
- QPID_BROKER_EXTERN std::string getAppId() const;
- framing::FieldTable& getOrInsertHeaders();
- QPID_BROKER_EXTERN bool isPersistent() const;
- bool requiresAccept();
-
- QPID_BROKER_EXTERN void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e);
- void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e);
- bool hasExpired();
- sys::AbsTime getExpiration() const { return expiration; }
- void adjustTtl();
-
- framing::FrameSet& getFrames() { return frames; }
- const framing::FrameSet& getFrames() const { return frames; }
-
- template <class T> T* getProperties() {
- qpid::framing::AMQHeaderBody* p = frames.getHeaders();
- return p->get<T>(true);
- }
-
- template <class T> const T* getProperties() const {
- const qpid::framing::AMQHeaderBody* p = frames.getHeaders();
- return p->get<T>(true);
- }
-
- template <class T> const T* hasProperties() const {
- const qpid::framing::AMQHeaderBody* p = frames.getHeaders();
- return p->get<T>();
- }
-
- template <class T> const T* getMethod() const {
- return frames.as<T>();
- }
-
- template <class T> T* getMethod() {
- return frames.as<T>();
- }
-
- template <class T> bool isA() const {
- return frames.isA<T>();
- }
-
- uint32_t getRequiredCredit();
-
- void encode(framing::Buffer& buffer) const;
- void encodeContent(framing::Buffer& buffer) const;
-
- /**
- * @returns the size of the buffer needed to encode this
- * message in its entirety
- */
- uint32_t encodedSize() const;
- /**
- * @returns the size of the buffer needed to encode the
- * 'header' of this message (not just the header frame,
- * but other meta data e.g.routing key and exchange)
- */
- uint32_t encodedHeaderSize() const;
- uint32_t encodedContentSize() const;
-
- QPID_BROKER_EXTERN void decodeHeader(framing::Buffer& buffer);
- QPID_BROKER_EXTERN void decodeContent(framing::Buffer& buffer);
-
- void QPID_BROKER_EXTERN tryReleaseContent();
- void releaseContent();
- void releaseContent(MessageStore* s);//deprecated, use 'setStore(store); releaseContent();' instead
- void destroy();
-
- bool getContentFrame(const Queue& queue, framing::AMQFrame& frame, uint16_t maxContentSize, uint64_t offset) const;
- QPID_BROKER_EXTERN void sendContent(const Queue& queue, framing::FrameHandler& out, uint16_t maxFrameSize) const;
- void sendHeader(framing::FrameHandler& out, uint16_t maxFrameSize) const;
-
- QPID_BROKER_EXTERN bool isContentLoaded() const;
-
- bool isExcluded(const std::vector<std::string>& excludes) const;
- void addTraceId(const std::string& id);
-
- void forcePersistent();
- bool isForcedPersistent();
-
-
- /** Call cb when dequeue is complete, may call immediately. Holds cb by reference. */
- void setDequeueCompleteCallback(MessageCallback& cb);
- void resetDequeueCompleteCallback();
-
- uint8_t getPriority() const;
- bool getIsManagementMessage() const;
- void setIsManagementMessage(bool b);
- private:
- MessageAdapter& getAdapter() const;
- void allDequeuesComplete();
-
- mutable sys::Mutex lock;
- framing::FrameSet frames;
- mutable boost::shared_ptr<Exchange> exchange;
- mutable uint64_t persistenceId;
- bool redelivered;
- bool loaded;
- bool staged;
- bool forcePersistentPolicy; // used to force message as durable, via a broker policy
- ConnectionToken* publisher;
- mutable MessageAdapter* adapter;
- qpid::sys::AbsTime expiration;
- boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
-
- static TransferAdapter TRANSFER;
-
- mutable boost::intrusive_ptr<Message> empty;
-
- sys::Monitor callbackLock;
- MessageCallback* dequeueCallback;
- bool inCallback;
-
- uint32_t requiredCredit;
- bool isManagementMessage;
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/MessageAdapter.cpp b/cpp/src/qpid/broker/MessageAdapter.cpp
deleted file mode 100644
index 0eb4a6fa22..0000000000
--- a/cpp/src/qpid/broker/MessageAdapter.cpp
+++ /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.
- *
- */
-
-#include "qpid/broker/MessageAdapter.h"
-
-#include "qpid/framing/DeliveryProperties.h"
-#include "qpid/framing/MessageProperties.h"
-#include "qpid/framing/MessageTransferBody.h"
-
-namespace {
- const std::string empty;
-}
-
-namespace qpid {
-namespace broker{
-
- std::string TransferAdapter::getRoutingKey(const framing::FrameSet& f)
- {
- const framing::DeliveryProperties* p = f.getHeaders()->get<framing::DeliveryProperties>();
- return p ? p->getRoutingKey() : empty;
- }
-
- std::string TransferAdapter::getExchange(const framing::FrameSet& f)
- {
- return f.as<framing::MessageTransferBody>()->getDestination();
- }
-
- bool TransferAdapter::isImmediate(const framing::FrameSet&)
- {
- //TODO: delete this, immediate is no longer part of the spec
- return false;
- }
-
- const framing::FieldTable* TransferAdapter::getApplicationHeaders(const framing::FrameSet& f)
- {
- const framing::MessageProperties* p = f.getHeaders()->get<framing::MessageProperties>();
- return p ? &(p->getApplicationHeaders()) : 0;
- }
-
- bool TransferAdapter::isPersistent(const framing::FrameSet& f)
- {
- const framing::DeliveryProperties* p = f.getHeaders()->get<framing::DeliveryProperties>();
- return p && p->getDeliveryMode() == 2;
- }
-
- bool TransferAdapter::requiresAccept(const framing::FrameSet& f)
- {
- const framing::MessageTransferBody* b = f.as<framing::MessageTransferBody>();
- return b && b->getAcceptMode() == 0/*EXPLICIT == 0*/;
- }
-
- uint8_t TransferAdapter::getPriority(const framing::FrameSet& f)
- {
- const framing::DeliveryProperties* p = f.getHeaders()->get<framing::DeliveryProperties>();
- return p ? p->getPriority() : 0;
- }
-
- std::string TransferAdapter::getAppId(const framing::FrameSet& f)
- {
- const framing::MessageProperties* p = f.getHeaders()->get<framing::MessageProperties>();
- return p ? p->getAppId() : empty;
- }
-}}
diff --git a/cpp/src/qpid/broker/MessageAdapter.h b/cpp/src/qpid/broker/MessageAdapter.h
deleted file mode 100644
index df50db4063..0000000000
--- a/cpp/src/qpid/broker/MessageAdapter.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef _broker_MessageAdapter_h
-#define _broker_MessageAdapter_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <string>
-#include "qpid/framing/FieldTable.h"
-#include "qpid/framing/FrameSet.h"
-
-namespace qpid {
-namespace broker {
-
-// TODO aconway 2007-11-09: No longer needed, we only have one type of message.
-struct MessageAdapter
-{
- virtual ~MessageAdapter() {}
-
- virtual std::string getRoutingKey(const framing::FrameSet& f) = 0;
- virtual std::string getExchange(const framing::FrameSet& f) = 0;
- virtual bool isImmediate(const framing::FrameSet& f) = 0;
- virtual const framing::FieldTable* getApplicationHeaders(const framing::FrameSet& f) = 0;
- virtual bool isPersistent(const framing::FrameSet& f) = 0;
- virtual bool requiresAccept(const framing::FrameSet& f) = 0;
- virtual uint8_t getPriority(const framing::FrameSet& f) = 0;
- virtual std::string getAppId(const framing::FrameSet& f) = 0;
-};
-
-struct TransferAdapter : MessageAdapter
-{
- virtual std::string getRoutingKey(const framing::FrameSet& f);
- virtual std::string getExchange(const framing::FrameSet& f);
- virtual const framing::FieldTable* getApplicationHeaders(const framing::FrameSet& f);
- virtual bool isPersistent(const framing::FrameSet& f);
- bool isImmediate(const framing::FrameSet&);
- bool requiresAccept(const framing::FrameSet& f);
- uint8_t getPriority(const framing::FrameSet& f);
- virtual std::string getAppId(const framing::FrameSet& f);
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/MessageBuilder.cpp b/cpp/src/qpid/broker/MessageBuilder.cpp
deleted file mode 100644
index a6d605c296..0000000000
--- a/cpp/src/qpid/broker/MessageBuilder.cpp
+++ /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.
- *
- */
-#include "qpid/broker/MessageBuilder.h"
-
-#include "qpid/broker/Message.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/NullMessageStore.h"
-#include "qpid/framing/AMQFrame.h"
-#include "qpid/framing/reply_exceptions.h"
-
-using boost::intrusive_ptr;
-using namespace qpid::broker;
-using namespace qpid::framing;
-
-namespace
-{
- std::string type_str(uint8_t type);
- const std::string QPID_MANAGEMENT("qpid.management");
-}
-
-MessageBuilder::MessageBuilder(MessageStore* const _store) :
- state(DORMANT), store(_store) {}
-
-void MessageBuilder::handle(AMQFrame& frame)
-{
- uint8_t type = frame.getBody()->type();
- switch(state) {
- case METHOD:
- checkType(METHOD_BODY, type);
- state = HEADER;
- break;
- case HEADER:
- if (type == CONTENT_BODY) {
- //TODO: rethink how to handle non-existent headers(?)...
- //didn't get a header: add in a dummy
- AMQFrame header((AMQHeaderBody()));
- header.setBof(false);
- header.setEof(false);
- message->getFrames().append(header);
- } else if (type != HEADER_BODY) {
- throw CommandInvalidException(
- QPID_MSG("Invalid frame sequence for message, expected header or content got "
- << type_str(type) << ")"));
- }
- state = CONTENT;
- break;
- case CONTENT:
- checkType(CONTENT_BODY, type);
- break;
- default:
- throw CommandInvalidException(QPID_MSG("Invalid frame sequence for message (state=" << state << ")"));
- }
- message->getFrames().append(frame);
-}
-
-void MessageBuilder::end()
-{
- message = 0;
- state = DORMANT;
-}
-
-void MessageBuilder::start(const SequenceNumber& id)
-{
- message = intrusive_ptr<Message>(new Message(id));
- message->setStore(store);
- state = METHOD;
-}
-
-namespace {
-
-const std::string HEADER_BODY_S = "HEADER";
-const std::string METHOD_BODY_S = "METHOD";
-const std::string CONTENT_BODY_S = "CONTENT";
-const std::string HEARTBEAT_BODY_S = "HEARTBEAT";
-const std::string UNKNOWN = "unknown";
-
-std::string type_str(uint8_t type)
-{
- switch(type) {
- case METHOD_BODY: return METHOD_BODY_S;
- case HEADER_BODY: return HEADER_BODY_S;
- case CONTENT_BODY: return CONTENT_BODY_S;
- case HEARTBEAT_BODY: return HEARTBEAT_BODY_S;
- }
- return UNKNOWN;
-}
-
-}
-
-void MessageBuilder::checkType(uint8_t expected, uint8_t actual)
-{
- if (expected != actual) {
- throw CommandInvalidException(QPID_MSG("Invalid frame sequence for message (expected "
- << type_str(expected) << " got " << type_str(actual) << ")"));
- }
-}
diff --git a/cpp/src/qpid/broker/MessageBuilder.h b/cpp/src/qpid/broker/MessageBuilder.h
deleted file mode 100644
index b99b8efee6..0000000000
--- a/cpp/src/qpid/broker/MessageBuilder.h
+++ /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.
- *
- */
-#ifndef _MessageBuilder_
-#define _MessageBuilder_
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/SequenceNumber.h"
-#include "qpid/RefCounted.h"
-
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
- namespace broker {
- class Message;
- class MessageStore;
-
- class QPID_BROKER_CLASS_EXTERN MessageBuilder : public framing::FrameHandler{
- public:
- QPID_BROKER_EXTERN MessageBuilder(MessageStore* const store);
- QPID_BROKER_EXTERN void handle(framing::AMQFrame& frame);
- boost::intrusive_ptr<Message> getMessage() { return message; }
- QPID_BROKER_EXTERN void start(const framing::SequenceNumber& id);
- void end();
- private:
- enum State {DORMANT, METHOD, HEADER, CONTENT};
- State state;
- boost::intrusive_ptr<Message> message;
- MessageStore* const store;
-
- void checkType(uint8_t expected, uint8_t actual);
- };
- }
-}
-
-
-#endif
-
diff --git a/cpp/src/qpid/broker/MessageDeque.cpp b/cpp/src/qpid/broker/MessageDeque.cpp
deleted file mode 100644
index 24b8f6f895..0000000000
--- a/cpp/src/qpid/broker/MessageDeque.cpp
+++ /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.
- *
- */
-#include "qpid/broker/MessageDeque.h"
-#include "qpid/broker/QueuedMessage.h"
-
-namespace qpid {
-namespace broker {
-
-size_t MessageDeque::size()
-{
- return messages.size();
-}
-
-bool MessageDeque::empty()
-{
- return messages.empty();
-}
-
-void MessageDeque::reinsert(const QueuedMessage& message)
-{
- messages.insert(lower_bound(messages.begin(), messages.end(), message), message);
-}
-
-MessageDeque::Deque::iterator MessageDeque::seek(const framing::SequenceNumber& position)
-{
- if (!messages.empty()) {
- QueuedMessage comp;
- comp.position = position;
- unsigned long diff = position.getValue() - messages.front().position.getValue();
- long maxEnd = diff < messages.size()? diff : messages.size();
- return lower_bound(messages.begin(),messages.begin()+maxEnd,comp);
- } else {
- return messages.end();
- }
-}
-
-bool MessageDeque::find(const framing::SequenceNumber& position, QueuedMessage& message, bool remove)
-{
- Deque::iterator i = seek(position);
- if (i != messages.end() && i->position == position) {
- message = *i;
- if (remove) messages.erase(i);
- return true;
- } else {
- return false;
- }
-}
-
-bool MessageDeque::remove(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- return find(position, message, true);
-}
-
-bool MessageDeque::find(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- return find(position, message, false);
-}
-
-bool MessageDeque::next(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- if (messages.empty()) {
- return false;
- } else if (position < front().position) {
- message = front();
- return true;
- } else {
- Deque::iterator i = seek(position+1);
- if (i != messages.end()) {
- message = *i;
- return true;
- } else {
- return false;
- }
- }
-}
-
-QueuedMessage& MessageDeque::front()
-{
- return messages.front();
-}
-
-void MessageDeque::pop()
-{
- if (!messages.empty()) {
- messages.pop_front();
- }
-}
-
-bool MessageDeque::pop(QueuedMessage& out)
-{
- if (messages.empty()) {
- return false;
- } else {
- out = front();
- messages.pop_front();
- return true;
- }
-}
-
-bool MessageDeque::push(const QueuedMessage& added, QueuedMessage& /*not needed*/)
-{
- messages.push_back(added);
- return false;//adding a message never causes one to be removed for deque
-}
-
-void MessageDeque::foreach(Functor f)
-{
- std::for_each(messages.begin(), messages.end(), f);
-}
-
-void MessageDeque::removeIf(Predicate p)
-{
- for (Deque::iterator i = messages.begin(); i != messages.end();) {
- if (p(*i)) {
- i = messages.erase(i);
- } else {
- ++i;
- }
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/MessageDeque.h b/cpp/src/qpid/broker/MessageDeque.h
deleted file mode 100644
index 0e1aef2986..0000000000
--- a/cpp/src/qpid/broker/MessageDeque.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef QPID_BROKER_MESSAGEDEQUE_H
-#define QPID_BROKER_MESSAGEDEQUE_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/Messages.h"
-#include "qpid/broker/QueuedMessage.h"
-#include <deque>
-
-namespace qpid {
-namespace broker {
-
-/**
- * Provides the standard FIFO queue behaviour.
- */
-class MessageDeque : public Messages
-{
- public:
- size_t size();
- bool empty();
-
- void reinsert(const QueuedMessage&);
- bool remove(const framing::SequenceNumber&, QueuedMessage&);
- bool find(const framing::SequenceNumber&, QueuedMessage&);
- bool next(const framing::SequenceNumber&, QueuedMessage&);
-
- QueuedMessage& front();
- void pop();
- bool pop(QueuedMessage&);
- bool push(const QueuedMessage& added, QueuedMessage& removed);
-
- void foreach(Functor);
- void removeIf(Predicate);
-
- private:
- typedef std::deque<QueuedMessage> Deque;
- Deque messages;
-
- Deque::iterator seek(const framing::SequenceNumber&);
- bool find(const framing::SequenceNumber&, QueuedMessage&, bool remove);
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_MESSAGEDEQUE_H*/
diff --git a/cpp/src/qpid/broker/MessageMap.cpp b/cpp/src/qpid/broker/MessageMap.cpp
deleted file mode 100644
index 39e23df533..0000000000
--- a/cpp/src/qpid/broker/MessageMap.cpp
+++ /dev/null
@@ -1,166 +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.
- *
- */
-#include "qpid/broker/MessageMap.h"
-#include "qpid/broker/QueuedMessage.h"
-
-namespace qpid {
-namespace broker {
-namespace {
-const std::string EMPTY;
-}
-
-std::string MessageMap::getKey(const QueuedMessage& message)
-{
- const framing::FieldTable* ft = message.payload->getApplicationHeaders();
- if (ft) return ft->getAsString(key);
- else return EMPTY;
-}
-
-size_t MessageMap::size()
-{
- return messages.size();
-}
-
-bool MessageMap::empty()
-{
- return messages.empty();
-}
-
-void MessageMap::reinsert(const QueuedMessage& message)
-{
- std::string key = getKey(message);
- Index::iterator i = index.find(key);
- if (i == index.end()) {
- index[key] = message;
- messages[message.position] = message;
- } //else message has already been replaced
-}
-
-bool MessageMap::remove(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- Ordering::iterator i = messages.find(position);
- if (i != messages.end()) {
- message = i->second;
- erase(i);
- return true;
- } else {
- return false;
- }
-}
-
-bool MessageMap::find(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- Ordering::iterator i = messages.find(position);
- if (i != messages.end()) {
- message = i->second;
- return true;
- } else {
- return false;
- }
-}
-
-bool MessageMap::next(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- if (!messages.empty() && position < front().position) {
- message = front();
- return true;
- } else {
- Ordering::iterator i = messages.lower_bound(position+1);
- if (i != messages.end()) {
- message = i->second;
- return true;
- } else {
- return false;
- }
- }
-}
-
-QueuedMessage& MessageMap::front()
-{
- return messages.begin()->second;
-}
-
-void MessageMap::pop()
-{
- QueuedMessage dummy;
- pop(dummy);
-}
-
-bool MessageMap::pop(QueuedMessage& out)
-{
- Ordering::iterator i = messages.begin();
- if (i != messages.end()) {
- out = i->second;
- erase(i);
- return true;
- } else {
- return false;
- }
-}
-
-const QueuedMessage& MessageMap::replace(const QueuedMessage& original, const QueuedMessage& update)
-{
- messages.erase(original.position);
- messages[update.position] = update;
- return update;
-}
-
-bool MessageMap::push(const QueuedMessage& added, QueuedMessage& removed)
-{
- std::pair<Index::iterator, bool> result = index.insert(Index::value_type(getKey(added), added));
- if (result.second) {
- //there was no previous message for this key; nothing needs to
- //be removed, just add the message into its correct position
- messages[added.position] = added;
- return false;
- } else {
- //there is already a message with that key which needs to be replaced
- removed = result.first->second;
- result.first->second = replace(result.first->second, added);
- return true;
- }
-}
-
-void MessageMap::foreach(Functor f)
-{
- for (Ordering::iterator i = messages.begin(); i != messages.end(); ++i) {
- f(i->second);
- }
-}
-
-void MessageMap::removeIf(Predicate p)
-{
- for (Ordering::iterator i = messages.begin(); i != messages.end(); i++) {
- if (p(i->second)) {
- erase(i);
- }
- }
-}
-
-void MessageMap::erase(Ordering::iterator i)
-{
- index.erase(getKey(i->second));
- messages.erase(i);
-}
-
-MessageMap::MessageMap(const std::string& k) : key(k) {}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/MessageMap.h b/cpp/src/qpid/broker/MessageMap.h
deleted file mode 100644
index 1128a1d54a..0000000000
--- a/cpp/src/qpid/broker/MessageMap.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef QPID_BROKER_MESSAGEMAP_H
-#define QPID_BROKER_MESSAGEMAP_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/Messages.h"
-#include "qpid/framing/SequenceNumber.h"
-#include <map>
-#include <string>
-
-namespace qpid {
-namespace broker {
-
-/**
- * Provides a last value queue behaviour, whereby a messages replace
- * any previous message with the same value for a defined property
- * (i.e. the key).
- */
-class MessageMap : public Messages
-{
- public:
- MessageMap(const std::string& key);
- virtual ~MessageMap() {}
-
- size_t size();
- bool empty();
-
- void reinsert(const QueuedMessage&);
- virtual bool remove(const framing::SequenceNumber&, QueuedMessage&);
- bool find(const framing::SequenceNumber&, QueuedMessage&);
- virtual bool next(const framing::SequenceNumber&, QueuedMessage&);
-
- QueuedMessage& front();
- void pop();
- bool pop(QueuedMessage&);
- virtual bool push(const QueuedMessage& added, QueuedMessage& removed);
-
- void foreach(Functor);
- virtual void removeIf(Predicate);
-
- protected:
- typedef std::map<std::string, QueuedMessage> Index;
- typedef std::map<framing::SequenceNumber, QueuedMessage> Ordering;
- const std::string key;
- Index index;
- Ordering messages;
-
- std::string getKey(const QueuedMessage&);
- virtual const QueuedMessage& replace(const QueuedMessage&, const QueuedMessage&);
- void erase(Ordering::iterator);
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_MESSAGEMAP_H*/
diff --git a/cpp/src/qpid/broker/MessageStore.h b/cpp/src/qpid/broker/MessageStore.h
deleted file mode 100644
index ab0225ef6b..0000000000
--- a/cpp/src/qpid/broker/MessageStore.h
+++ /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.
- *
- */
-#ifndef _MessageStore_
-#define _MessageStore_
-
-#include "qpid/broker/PersistableExchange.h"
-#include "qpid/broker/PersistableMessage.h"
-#include "qpid/broker/PersistableQueue.h"
-#include "qpid/broker/PersistableConfig.h"
-#include "qpid/broker/RecoveryManager.h"
-#include "qpid/broker/TransactionalStore.h"
-#include "qpid/framing/FieldTable.h"
-
-#include <qpid/Options.h>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-/**
- * An abstraction of the persistent storage for messages. (In
- * all methods, any pointers/references to queues or messages
- * are valid only for the duration of the call).
- */
-class MessageStore : public TransactionalStore, public Recoverable {
- public:
-
- /**
- * If called after initialization but before recovery, will discard the database
- * content and reinitialize as though it were a new installation. If the parameter
- * saveStoreContent is true, the content of the store will be saved in such a way
- * that the truncate can be reversed. This is used when cluster nodes recover and
- * must get their content from a cluster sync rather than directly from the store.
- *
- * @param saveStoreContent If true, will move content of the store to a backup
- * location where they may be restored later if needed. It is
- * not necessary to save more than one prior version of the
- * store.
- */
- virtual void truncateInit(const bool saveStoreContent = false) = 0;
-
- /**
- * Record the existence of a durable queue
- */
- virtual void create(PersistableQueue& queue,
- const framing::FieldTable& args) = 0;
- /**
- * Destroy a durable queue
- */
- virtual void destroy(PersistableQueue& queue) = 0;
-
- /**
- * Record the existence of a durable exchange
- */
- virtual void create(const PersistableExchange& exchange,
- const framing::FieldTable& args) = 0;
- /**
- * Destroy a durable exchange
- */
- virtual void destroy(const PersistableExchange& exchange) = 0;
-
- /**
- * Record a binding
- */
- virtual void bind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args) = 0;
-
- /**
- * Forget a binding
- */
- virtual void unbind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args) = 0;
-
- /**
- * Record generic durable configuration
- */
- virtual void create(const PersistableConfig& config) = 0;
-
- /**
- * Destroy generic durable configuration
- */
- virtual void destroy(const PersistableConfig& config) = 0;
-
- /**
- * Stores a messages before it has been enqueued
- * (enqueueing automatically stores the message so this is
- * only required if storage is required prior to that
- * point). If the message has not yet been stored it will
- * store the headers as well as any content passed in. A
- * persistence id will be set on the message which can be
- * used to load the content or to append to it.
- */
- virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg) = 0;
-
- /**
- * Destroys a previously staged message. This only needs
- * to be called if the message is never enqueued. (Once
- * enqueued, deletion will be automatic when the message
- * is dequeued from all queues it was enqueued onto).
- */
- virtual void destroy(PersistableMessage& msg) = 0;
-
- /**
- * Appends content to a previously staged message
- */
- virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg,
- const std::string& data) = 0;
-
- /**
- * Loads (a section) of content data for the specified
- * message (previously stored through a call to stage or
- * enqueue) into data. The offset refers to the content
- * only (i.e. an offset of 0 implies that the start of the
- * content should be loaded, not the headers or related
- * meta-data).
- */
- virtual void loadContent(const qpid::broker::PersistableQueue& queue,
- const boost::intrusive_ptr<const PersistableMessage>& msg,
- std::string& data, uint64_t offset, uint32_t length) = 0;
-
- /**
- * Enqueues a message, storing the message if it has not
- * been previously stored and recording that the given
- * message is on the given queue.
- *
- * Note: that this is async so the return of the function does
- * not mean the opperation is complete.
- *
- * @param msg the message to enqueue
- * @param queue the name of the queue onto which it is to be enqueued
- * @param xid (a pointer to) an identifier of the
- * distributed transaction in which the operation takes
- * place or null for 'local' transactions
- */
- virtual void enqueue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue) = 0;
-
- /**
- * Dequeues a message, recording that the given message is
- * no longer on the given queue and deleting the message
- * if it is no longer on any other queue.
- *
- * Note: that this is async so the return of the function does
- * not mean the opperation is complete.
- *
- * @param msg the message to dequeue
- * @param queue the name of the queue from which it is to be dequeued
- * @param xid (a pointer to) an identifier of the
- * distributed transaction in which the operation takes
- * place or null for 'local' transactions
- */
- virtual void dequeue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue) = 0;
-
- /**
- * Flushes all async messages to disk for the specified queue
- *
- * Note: that this is async so the return of the function does
- * not mean the opperation is complete.
- *
- * @param queue the name of the queue from which it is to be dequeued
- */
- virtual void flush(const qpid::broker::PersistableQueue& queue)=0;
-
- /**
- * Returns the number of outstanding AIO's for a given queue
- *
- * If 0, than all the enqueue / dequeues have been stored
- * to disk
- *
- * @param queue the name of the queue to check for outstanding AIO
- */
- virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue) = 0;
-
-
- virtual ~MessageStore(){}
-};
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/MessageStoreModule.cpp b/cpp/src/qpid/broker/MessageStoreModule.cpp
deleted file mode 100644
index cd9fd4c933..0000000000
--- a/cpp/src/qpid/broker/MessageStoreModule.cpp
+++ /dev/null
@@ -1,180 +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.
- *
- */
-
-#include "qpid/broker/MessageStoreModule.h"
-#include "qpid/broker/NullMessageStore.h"
-#include <iostream>
-
-// This transfer protects against the unloading of the store lib prior to the handling of the exception
-#define TRANSFER_EXCEPTION(fn) try { fn; } catch (std::exception& e) { throw Exception(e.what()); }
-
-using boost::intrusive_ptr;
-using qpid::framing::FieldTable;
-using std::string;
-
-namespace qpid {
-namespace broker {
-
-MessageStoreModule::MessageStoreModule(boost::shared_ptr<MessageStore>& _store)
- : store(_store) {}
-
-MessageStoreModule::~MessageStoreModule()
-{
-}
-
-bool MessageStoreModule::init(const Options*) { return true; }
-
-void MessageStoreModule::truncateInit(const bool pushDownStoreFiles)
-{
- TRANSFER_EXCEPTION(store->truncateInit(pushDownStoreFiles));
-}
-
-void MessageStoreModule::create(PersistableQueue& queue, const FieldTable& args)
-{
- TRANSFER_EXCEPTION(store->create(queue, args));
-}
-
-void MessageStoreModule::destroy(PersistableQueue& queue)
-{
- TRANSFER_EXCEPTION(store->destroy(queue));
-}
-
-void MessageStoreModule::create(const PersistableExchange& exchange, const FieldTable& args)
-{
- TRANSFER_EXCEPTION(store->create(exchange, args));
-}
-
-void MessageStoreModule::destroy(const PersistableExchange& exchange)
-{
- TRANSFER_EXCEPTION(store->destroy(exchange));
-}
-
-void MessageStoreModule::bind(const PersistableExchange& e, const PersistableQueue& q,
- const std::string& k, const framing::FieldTable& a)
-{
- TRANSFER_EXCEPTION(store->bind(e, q, k, a));
-}
-
-void MessageStoreModule::unbind(const PersistableExchange& e, const PersistableQueue& q,
- const std::string& k, const framing::FieldTable& a)
-{
- TRANSFER_EXCEPTION(store->unbind(e, q, k, a));
-}
-
-void MessageStoreModule::create(const PersistableConfig& config)
-{
- TRANSFER_EXCEPTION(store->create(config));
-}
-
-void MessageStoreModule::destroy(const PersistableConfig& config)
-{
- TRANSFER_EXCEPTION(store->destroy(config));
-}
-
-void MessageStoreModule::recover(RecoveryManager& registry)
-{
- TRANSFER_EXCEPTION(store->recover(registry));
-}
-
-void MessageStoreModule::stage(const intrusive_ptr<PersistableMessage>& msg)
-{
- TRANSFER_EXCEPTION(store->stage(msg));
-}
-
-void MessageStoreModule::destroy(PersistableMessage& msg)
-{
- TRANSFER_EXCEPTION(store->destroy(msg));
-}
-
-void MessageStoreModule::appendContent(const intrusive_ptr<const PersistableMessage>& msg,
- const std::string& data)
-{
- TRANSFER_EXCEPTION(store->appendContent(msg, data));
-}
-
-void MessageStoreModule::loadContent(
- const qpid::broker::PersistableQueue& queue,
- const intrusive_ptr<const PersistableMessage>& msg,
- string& data, uint64_t offset, uint32_t length)
-{
- TRANSFER_EXCEPTION(store->loadContent(queue, msg, data, offset, length));
-}
-
-void MessageStoreModule::enqueue(TransactionContext* ctxt,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue)
-{
- TRANSFER_EXCEPTION(store->enqueue(ctxt, msg, queue));
-}
-
-void MessageStoreModule::dequeue(TransactionContext* ctxt,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue)
-{
- TRANSFER_EXCEPTION(store->dequeue(ctxt, msg, queue));
-}
-
-void MessageStoreModule::flush(const qpid::broker::PersistableQueue& queue)
-{
- TRANSFER_EXCEPTION(store->flush(queue));
-}
-
-uint32_t MessageStoreModule::outstandingQueueAIO(const PersistableQueue& queue)
-{
- TRANSFER_EXCEPTION(return store->outstandingQueueAIO(queue));
-}
-
-std::auto_ptr<TransactionContext> MessageStoreModule::begin()
-{
- TRANSFER_EXCEPTION(return store->begin());
-}
-
-std::auto_ptr<TPCTransactionContext> MessageStoreModule::begin(const std::string& xid)
-{
- TRANSFER_EXCEPTION(return store->begin(xid));
-}
-
-void MessageStoreModule::prepare(TPCTransactionContext& txn)
-{
- TRANSFER_EXCEPTION(store->prepare(txn));
-}
-
-void MessageStoreModule::commit(TransactionContext& ctxt)
-{
- TRANSFER_EXCEPTION(store->commit(ctxt));
-}
-
-void MessageStoreModule::abort(TransactionContext& ctxt)
-{
- TRANSFER_EXCEPTION(store->abort(ctxt));
-}
-
-void MessageStoreModule::collectPreparedXids(std::set<std::string>& xids)
-{
- TRANSFER_EXCEPTION(store->collectPreparedXids(xids));
-}
-
-bool MessageStoreModule::isNull() const
-{
- return NullMessageStore::isNullStore(store.get());
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/MessageStoreModule.h b/cpp/src/qpid/broker/MessageStoreModule.h
deleted file mode 100644
index 56b5a3c1ae..0000000000
--- a/cpp/src/qpid/broker/MessageStoreModule.h
+++ /dev/null
@@ -1,87 +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.
- *
- */
-#ifndef _MessageStoreModule_
-#define _MessageStoreModule_
-
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/RecoveryManager.h"
-
-#include <boost/intrusive_ptr.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-/**
- * A null implementation of the MessageStore interface
- */
-class MessageStoreModule : public MessageStore
-{
- boost::shared_ptr<MessageStore> store;
- public:
- MessageStoreModule(boost::shared_ptr<MessageStore>& store);
-
- bool init(const Options* options);
- void truncateInit(const bool pushDownStoreFiles = false);
- std::auto_ptr<TransactionContext> begin();
- std::auto_ptr<TPCTransactionContext> begin(const std::string& xid);
- void prepare(TPCTransactionContext& txn);
- void commit(TransactionContext& txn);
- void abort(TransactionContext& txn);
- void collectPreparedXids(std::set<std::string>& xids);
-
- void create(PersistableQueue& queue, const framing::FieldTable& args);
- void destroy(PersistableQueue& queue);
- void create(const PersistableExchange& exchange, const framing::FieldTable& args);
- void destroy(const PersistableExchange& exchange);
- void bind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args);
- void unbind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args);
- void create(const PersistableConfig& config);
- void destroy(const PersistableConfig& config);
- void recover(RecoveryManager& queues);
- void stage(const boost::intrusive_ptr<PersistableMessage>& msg);
- void destroy(PersistableMessage& msg);
- void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg, const std::string& data);
- void loadContent(const qpid::broker::PersistableQueue& queue,
- const boost::intrusive_ptr<const PersistableMessage>& msg, std::string& data,
- uint64_t offset, uint32_t length);
-
- void enqueue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- void dequeue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- uint32_t outstandingQueueAIO(const PersistableQueue& queue);
- void flush(const qpid::broker::PersistableQueue& queue);
- bool isNull() const;
-
- ~MessageStoreModule();
-};
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/Messages.h b/cpp/src/qpid/broker/Messages.h
deleted file mode 100644
index 0d75417640..0000000000
--- a/cpp/src/qpid/broker/Messages.h
+++ /dev/null
@@ -1,117 +0,0 @@
-#ifndef QPID_BROKER_MESSAGES_H
-#define QPID_BROKER_MESSAGES_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include <boost/function.hpp>
-
-namespace qpid {
-namespace framing {
-class SequenceNumber;
-}
-namespace broker {
-struct QueuedMessage;
-
-/**
- * This interface abstracts out the access to the messages held for
- * delivery by a Queue instance.
- */
-class Messages
-{
- public:
- typedef boost::function1<void, QueuedMessage&> Functor;
- typedef boost::function1<bool, QueuedMessage&> Predicate;
-
- virtual ~Messages() {}
- /**
- * @return the number of messages available for delivery.
- */
- virtual size_t size() = 0;
- /**
- * @return true if there are no messages for delivery, false otherwise
- */
- virtual bool empty() = 0;
-
- /**
- * Re-inserts a message back into its original position - used
- * when requeing released messages.
- */
- virtual void reinsert(const QueuedMessage&) = 0;
- /**
- * Remove the message at the specified position, returning true if
- * found, false otherwise. The removed message is passed back via
- * the second parameter.
- */
- virtual bool remove(const framing::SequenceNumber&, QueuedMessage&) = 0;
- /**
- * Find the message at the specified position, returning true if
- * found, false otherwise. The matched message is passed back via
- * the second parameter.
- */
- virtual bool find(const framing::SequenceNumber&, QueuedMessage&) = 0;
- /**
- * Return the next message to be given to a browsing subscrption
- * that has reached the specified poisition. The next messages is
- * passed back via the second parameter.
- *
- * @return true if there is another message, false otherwise.
- */
- virtual bool next(const framing::SequenceNumber&, QueuedMessage&) = 0;
-
- /**
- * Note: Caller is responsible for ensuring that there is a front
- * (e.g. empty() returns false)
- *
- * @return the next message to be delivered
- */
- virtual QueuedMessage& front() = 0;
- /**
- * Removes the front message
- */
- virtual void pop() = 0;
- /**
- * @return true if there is a mesage to be delivered - in which
- * case that message will be returned via the parameter and
- * removed - otherwise false.
- */
- virtual bool pop(QueuedMessage&) = 0;
- /**
- * Pushes a message to the back of the 'queue'. For some types of
- * queue this may cause another message to be removed; if that is
- * the case the method will return true and the removed message
- * will be passed out via the second parameter.
- */
- virtual bool push(const QueuedMessage& added, QueuedMessage& removed) = 0;
-
- /**
- * Apply the functor to each message held
- */
- virtual void foreach(Functor) = 0;
- /**
- * Remove every message held that for which the specified
- * predicate returns true
- */
- virtual void removeIf(Predicate) = 0;
- private:
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_MESSAGES_H*/
diff --git a/cpp/src/qpid/broker/NameGenerator.cpp b/cpp/src/qpid/broker/NameGenerator.cpp
deleted file mode 100644
index e7f193d546..0000000000
--- a/cpp/src/qpid/broker/NameGenerator.cpp
+++ /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.
- *
- */
-#include "qpid/broker/NameGenerator.h"
-#include <sstream>
-
-using namespace qpid::broker;
-
-NameGenerator::NameGenerator(const std::string& _base) : base(_base), counter(1) {}
-
-std::string NameGenerator::generate(){
- std::stringstream ss;
- ss << base << counter++;
- return ss.str();
-}
diff --git a/cpp/src/qpid/broker/NameGenerator.h b/cpp/src/qpid/broker/NameGenerator.h
deleted file mode 100644
index 6ea25c9797..0000000000
--- a/cpp/src/qpid/broker/NameGenerator.h
+++ /dev/null
@@ -1,39 +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.
- *
- */
-#ifndef _NameGenerator_
-#define _NameGenerator_
-
-#include <string>
-
-namespace qpid {
- namespace broker {
- class NameGenerator{
- const std::string base;
- unsigned int counter;
- public:
- NameGenerator(const std::string& base);
- std::string generate();
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/NullMessageStore.cpp b/cpp/src/qpid/broker/NullMessageStore.cpp
deleted file mode 100644
index 43f600eaf1..0000000000
--- a/cpp/src/qpid/broker/NullMessageStore.cpp
+++ /dev/null
@@ -1,167 +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.
- *
- */
-
-#include "qpid/broker/NullMessageStore.h"
-#include "qpid/broker/MessageStoreModule.h"
-#include "qpid/broker/RecoveryManager.h"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/reply_exceptions.h"
-
-#include <iostream>
-
-using boost::intrusive_ptr;
-
-namespace qpid{
-namespace broker{
-
-const std::string nullxid = "";
-
-class SimpleDummyCtxt : public TransactionContext {};
-
-class DummyCtxt : public TPCTransactionContext
-{
- const std::string xid;
-public:
- DummyCtxt(const std::string& _xid) : xid(_xid) {}
- static std::string getXid(TransactionContext& ctxt)
- {
- DummyCtxt* c(dynamic_cast<DummyCtxt*>(&ctxt));
- return c ? c->xid : nullxid;
- }
-};
-
-NullMessageStore::NullMessageStore() : nextPersistenceId(1) {}
-
-bool NullMessageStore::init(const Options* /*options*/) {return true;}
-
-void NullMessageStore::truncateInit(const bool /*pushDownStoreFiles*/) {}
-
-void NullMessageStore::create(PersistableQueue& queue, const framing::FieldTable& /*args*/)
-{
- queue.setPersistenceId(nextPersistenceId++);
-}
-
-void NullMessageStore::destroy(PersistableQueue&) {}
-
-void NullMessageStore::create(const PersistableExchange& exchange, const framing::FieldTable& /*args*/)
-{
- exchange.setPersistenceId(nextPersistenceId++);
-}
-
-void NullMessageStore::destroy(const PersistableExchange& ) {}
-
-void NullMessageStore::bind(const PersistableExchange&, const PersistableQueue&, const std::string&, const framing::FieldTable&){}
-
-void NullMessageStore::unbind(const PersistableExchange&, const PersistableQueue&, const std::string&, const framing::FieldTable&){}
-
-void NullMessageStore::create(const PersistableConfig& config)
-{
- config.setPersistenceId(nextPersistenceId++);
-}
-
-void NullMessageStore::destroy(const PersistableConfig&) {}
-
-void NullMessageStore::recover(RecoveryManager&) {}
-
-void NullMessageStore::stage(const intrusive_ptr<PersistableMessage>&) {}
-
-void NullMessageStore::destroy(PersistableMessage&) {}
-
-void NullMessageStore::appendContent(const intrusive_ptr<const PersistableMessage>&, const std::string&) {}
-
-void NullMessageStore::loadContent(const qpid::broker::PersistableQueue&,
- const intrusive_ptr<const PersistableMessage>&,
- std::string&, uint64_t, uint32_t)
-{
- throw qpid::framing::InternalErrorException("Can't load content; persistence not enabled");
-}
-
-void NullMessageStore::enqueue(TransactionContext*,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue&)
-{
- msg->enqueueComplete();
-}
-
-void NullMessageStore::dequeue(TransactionContext*,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue&)
-{
- msg->dequeueComplete();
-}
-
-void NullMessageStore::flush(const qpid::broker::PersistableQueue&) {}
-
-uint32_t NullMessageStore::outstandingQueueAIO(const PersistableQueue& ) {
- return 0;
-}
-
-std::auto_ptr<TransactionContext> NullMessageStore::begin()
-{
- return std::auto_ptr<TransactionContext>(new SimpleDummyCtxt());
-}
-
-std::auto_ptr<TPCTransactionContext> NullMessageStore::begin(const std::string& xid)
-{
- return std::auto_ptr<TPCTransactionContext>(new DummyCtxt(xid));
-}
-
-void NullMessageStore::prepare(TPCTransactionContext& ctxt)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
- prepared.insert(DummyCtxt::getXid(ctxt));
-}
-
-void NullMessageStore::commit(TransactionContext& ctxt)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
- prepared.erase(DummyCtxt::getXid(ctxt));
-}
-
-void NullMessageStore::abort(TransactionContext& ctxt)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
- prepared.erase(DummyCtxt::getXid(ctxt));
-}
-
-void NullMessageStore::collectPreparedXids(std::set<std::string>& out)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
- out.insert(prepared.begin(), prepared.end());
-}
-
-bool NullMessageStore::isNull() const
-{
- return true;
-}
-
-bool NullMessageStore::isNullStore(const MessageStore* store)
-{
- const MessageStoreModule* wrapper = dynamic_cast<const MessageStoreModule*>(store);
- if (wrapper) {
- return wrapper->isNull();
- } else {
- const NullMessageStore* test = dynamic_cast<const NullMessageStore*>(store);
- return test && test->isNull();
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/NullMessageStore.h b/cpp/src/qpid/broker/NullMessageStore.h
deleted file mode 100644
index c6f402662e..0000000000
--- a/cpp/src/qpid/broker/NullMessageStore.h
+++ /dev/null
@@ -1,100 +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.
- *
- */
-#ifndef _NullMessageStore_
-#define _NullMessageStore_
-
-#include <set>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/sys/Mutex.h"
-
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-/**
- * A null implementation of the MessageStore interface
- */
-class QPID_BROKER_CLASS_EXTERN NullMessageStore : public MessageStore
-{
- std::set<std::string> prepared;
- uint64_t nextPersistenceId;
- qpid::sys::Mutex lock;
- public:
- QPID_BROKER_EXTERN NullMessageStore();
-
- QPID_BROKER_EXTERN virtual bool init(const Options* options);
- QPID_BROKER_EXTERN virtual void truncateInit(const bool pushDownStoreFiles = false);
- QPID_BROKER_EXTERN virtual std::auto_ptr<TransactionContext> begin();
- QPID_BROKER_EXTERN virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid);
- QPID_BROKER_EXTERN virtual void prepare(TPCTransactionContext& txn);
- QPID_BROKER_EXTERN virtual void commit(TransactionContext& txn);
- QPID_BROKER_EXTERN virtual void abort(TransactionContext& txn);
- QPID_BROKER_EXTERN virtual void collectPreparedXids(std::set<std::string>& xids);
-
- QPID_BROKER_EXTERN virtual void create(PersistableQueue& queue,
- const framing::FieldTable& args);
- QPID_BROKER_EXTERN virtual void destroy(PersistableQueue& queue);
- QPID_BROKER_EXTERN virtual void create(const PersistableExchange& exchange,
- const framing::FieldTable& args);
- QPID_BROKER_EXTERN virtual void destroy(const PersistableExchange& exchange);
-
- QPID_BROKER_EXTERN virtual void bind(const PersistableExchange& exchange,
- const PersistableQueue& queue,
- const std::string& key,
- const framing::FieldTable& args);
- QPID_BROKER_EXTERN virtual void unbind(const PersistableExchange& exchange,
- const PersistableQueue& queue,
- const std::string& key,
- const framing::FieldTable& args);
- QPID_BROKER_EXTERN virtual void create(const PersistableConfig& config);
- QPID_BROKER_EXTERN virtual void destroy(const PersistableConfig& config);
- QPID_BROKER_EXTERN virtual void recover(RecoveryManager& queues);
- QPID_BROKER_EXTERN virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg);
- QPID_BROKER_EXTERN virtual void destroy(PersistableMessage& msg);
- QPID_BROKER_EXTERN virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg,
- const std::string& data);
- QPID_BROKER_EXTERN virtual void loadContent(const qpid::broker::PersistableQueue& queue,
- const boost::intrusive_ptr<const PersistableMessage>& msg,
- std::string& data,
- uint64_t offset,
- uint32_t length);
- QPID_BROKER_EXTERN virtual void enqueue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- QPID_BROKER_EXTERN virtual void dequeue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- QPID_BROKER_EXTERN virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue);
- QPID_BROKER_EXTERN virtual void flush(const qpid::broker::PersistableQueue& queue);
- ~NullMessageStore(){}
-
- QPID_BROKER_EXTERN virtual bool isNull() const;
- static bool isNullStore(const MessageStore*);
-};
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/OwnershipToken.h b/cpp/src/qpid/broker/OwnershipToken.h
deleted file mode 100644
index effd2f5b3c..0000000000
--- a/cpp/src/qpid/broker/OwnershipToken.h
+++ /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.
- *
- */
-#ifndef _OwnershipToken_
-#define _OwnershipToken_
-
-namespace qpid {
-namespace broker {
-
-class ConnectionToken;
-
-class OwnershipToken{
-public:
- virtual bool isLocal(const ConnectionToken* t) const = 0;
- virtual ~OwnershipToken(){}
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/Persistable.h b/cpp/src/qpid/broker/Persistable.h
deleted file mode 100644
index 36499c7a1a..0000000000
--- a/cpp/src/qpid/broker/Persistable.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef _broker_Persistable_h
-#define _broker_Persistable_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/framing/amqp_types.h"
-#include "qpid/framing/Buffer.h"
-#include "qpid/RefCounted.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Base class for all persistable objects
- */
-class Persistable : public RefCounted
-{
-public:
- /**
- * Allows the store to attach its own identifier to this object
- */
- virtual void setPersistenceId(uint64_t id) const = 0;
- /**
- * Returns any identifier the store may have attached to this
- * object
- */
- virtual uint64_t getPersistenceId() const = 0;
- /**
- * Encodes the persistable state of this object into the supplied
- * buffer
- */
- virtual void encode(framing::Buffer& buffer) const = 0;
- /**
- * @returns the size of the buffer needed to encode this object
- */
- virtual uint32_t encodedSize() const = 0;
-
- virtual ~Persistable() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/PersistableConfig.h b/cpp/src/qpid/broker/PersistableConfig.h
deleted file mode 100644
index 8ddb84d129..0000000000
--- a/cpp/src/qpid/broker/PersistableConfig.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _broker_PersistableConfig_h
-#define _broker_PersistableConfig_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <string>
-#include "qpid/broker/Persistable.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * The interface used by general-purpose persistable configuration for
- * the message store.
- */
-class PersistableConfig : public Persistable
-{
-public:
- virtual const std::string& getName() const = 0;
- virtual ~PersistableConfig() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/PersistableExchange.h b/cpp/src/qpid/broker/PersistableExchange.h
deleted file mode 100644
index e1a0853247..0000000000
--- a/cpp/src/qpid/broker/PersistableExchange.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _broker_PersistableExchange_h
-#define _broker_PersistableExchange_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <string>
-#include "qpid/broker/Persistable.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * The interface exchanges must expose to the MessageStore in order to be
- * persistable.
- */
-class PersistableExchange : public Persistable
-{
-public:
- virtual const std::string& getName() const = 0;
- virtual ~PersistableExchange() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/PersistableMessage.cpp b/cpp/src/qpid/broker/PersistableMessage.cpp
deleted file mode 100644
index 7ba28eb293..0000000000
--- a/cpp/src/qpid/broker/PersistableMessage.cpp
+++ /dev/null
@@ -1,161 +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.
- *
- */
-
-
-#include "qpid/broker/PersistableMessage.h"
-#include "qpid/broker/MessageStore.h"
-#include <iostream>
-
-using namespace qpid::broker;
-
-namespace qpid {
-namespace broker {
-
-class MessageStore;
-
-PersistableMessage::~PersistableMessage() {}
-
-PersistableMessage::PersistableMessage() :
- asyncDequeueCounter(0),
- store(0)
-{}
-
-void PersistableMessage::flush()
-{
- syncList copy;
- {
- sys::ScopedLock<sys::Mutex> l(storeLock);
- if (store) {
- copy = synclist;
- } else {
- return;//early exit as nothing to do
- }
- }
- for (syncList::iterator i = copy.begin(); i != copy.end(); ++i) {
- PersistableQueue::shared_ptr q(i->lock());
- if (q) {
- q->flush();
- }
- }
-}
-
-void PersistableMessage::setContentReleased()
-{
- contentReleaseState.released = true;
-}
-
-bool PersistableMessage::isContentReleased() const
-{
- return contentReleaseState.released;
-}
-
-
-bool PersistableMessage::isStoredOnQueue(PersistableQueue::shared_ptr queue){
- if (store && (queue->getPersistenceId()!=0)) {
- for (syncList::iterator i = synclist.begin(); i != synclist.end(); ++i) {
- PersistableQueue::shared_ptr q(i->lock());
- if (q && q->getPersistenceId() == queue->getPersistenceId()) return true;
- }
- }
- return false;
-}
-
-
-void PersistableMessage::addToSyncList(PersistableQueue::shared_ptr queue, MessageStore* _store) {
- if (_store){
- sys::ScopedLock<sys::Mutex> l(storeLock);
- store = _store;
- boost::weak_ptr<PersistableQueue> q(queue);
- synclist.push_back(q);
- }
-}
-
-void PersistableMessage::enqueueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store) {
- addToSyncList(queue, _store);
- enqueueStart();
-}
-
-bool PersistableMessage::isDequeueComplete() {
- sys::ScopedLock<sys::Mutex> l(asyncDequeueLock);
- return asyncDequeueCounter == 0;
-}
-
-void PersistableMessage::dequeueComplete() {
- bool notify = false;
- {
- sys::ScopedLock<sys::Mutex> l(asyncDequeueLock);
- if (asyncDequeueCounter > 0) {
- if (--asyncDequeueCounter == 0) {
- notify = true;
- }
- }
- }
- if (notify) allDequeuesComplete();
-}
-
-void PersistableMessage::dequeueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store) {
- if (_store){
- sys::ScopedLock<sys::Mutex> l(storeLock);
- store = _store;
- boost::weak_ptr<PersistableQueue> q(queue);
- synclist.push_back(q);
- }
- dequeueAsync();
-}
-
-void PersistableMessage::dequeueAsync() {
- sys::ScopedLock<sys::Mutex> l(asyncDequeueLock);
- asyncDequeueCounter++;
-}
-
-PersistableMessage::ContentReleaseState::ContentReleaseState() : blocked(false), requested(false), released(false) {}
-
-void PersistableMessage::setStore(MessageStore* s)
-{
- store = s;
-}
-
-void PersistableMessage::requestContentRelease()
-{
- contentReleaseState.requested = true;
-}
-void PersistableMessage::blockContentRelease()
-{
- contentReleaseState.blocked = true;
-}
-bool PersistableMessage::checkContentReleasable()
-{
- return contentReleaseState.requested && !contentReleaseState.blocked;
-}
-
-bool PersistableMessage::isContentReleaseBlocked()
-{
- return contentReleaseState.blocked;
-}
-
-bool PersistableMessage::isContentReleaseRequested()
-{
- return contentReleaseState.requested;
-}
-
-}}
-
-
diff --git a/cpp/src/qpid/broker/PersistableMessage.h b/cpp/src/qpid/broker/PersistableMessage.h
deleted file mode 100644
index d29c2c45b4..0000000000
--- a/cpp/src/qpid/broker/PersistableMessage.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#ifndef _broker_PersistableMessage_h
-#define _broker_PersistableMessage_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <string>
-#include <list>
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Persistable.h"
-#include "qpid/framing/amqp_types.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/broker/PersistableQueue.h"
-#include "qpid/broker/AsyncCompletion.h"
-
-namespace qpid {
-namespace broker {
-
-class MessageStore;
-
-/**
- * Base class for persistable messages.
- */
-class PersistableMessage : public Persistable
-{
- typedef std::list< boost::weak_ptr<PersistableQueue> > syncList;
- sys::Mutex asyncDequeueLock;
- sys::Mutex storeLock;
-
- /**
- * "Ingress" messages == messages sent _to_ the broker.
- * Tracks the number of outstanding asynchronous operations that must
- * complete before an inbound message can be considered fully received by the
- * broker. E.g. all enqueues have completed, the message has been written
- * to store, credit has been replenished, etc. Once all outstanding
- * operations have completed, the transfer of this message from the client
- * may be considered complete.
- */
- AsyncCompletion ingressCompletion;
-
- /**
- * Tracks the number of outstanding asynchronous dequeue
- * operations. When the message is dequeued asynchronously the
- * count is incremented; when that dequeue completes it is
- * decremented. Thus when it is 0, there are no outstanding
- * dequeues.
- */
- int asyncDequeueCounter;
-
- void dequeueAsync();
-
- syncList synclist;
- struct ContentReleaseState
- {
- bool blocked;
- bool requested;
- bool released;
-
- ContentReleaseState();
- };
- ContentReleaseState contentReleaseState;
-
- protected:
- /** Called when all dequeues are complete for this message. */
- virtual void allDequeuesComplete() = 0;
-
- void setContentReleased();
-
- MessageStore* store;
-
-
- public:
- typedef boost::shared_ptr<PersistableMessage> shared_ptr;
-
- /**
- * @returns the size of the headers when encoded
- */
- virtual uint32_t encodedHeaderSize() const = 0;
-
- virtual ~PersistableMessage();
-
- PersistableMessage();
-
- void flush();
-
- QPID_BROKER_EXTERN bool isContentReleased() const;
-
- QPID_BROKER_EXTERN void setStore(MessageStore*);
- void requestContentRelease();
- void blockContentRelease();
- bool checkContentReleasable();
- bool isContentReleaseBlocked();
- bool isContentReleaseRequested();
-
- virtual QPID_BROKER_EXTERN bool isPersistent() const = 0;
-
- /** track the progress of a message received by the broker - see ingressCompletion above */
- QPID_BROKER_INLINE_EXTERN bool isIngressComplete() { return ingressCompletion.isDone(); }
- QPID_BROKER_INLINE_EXTERN AsyncCompletion& getIngressCompletion() { return ingressCompletion; }
-
- QPID_BROKER_INLINE_EXTERN void enqueueStart() { ingressCompletion.startCompleter(); }
- QPID_BROKER_INLINE_EXTERN void enqueueComplete() { ingressCompletion.finishCompleter(); }
-
- QPID_BROKER_EXTERN void enqueueAsync(PersistableQueue::shared_ptr queue,
- MessageStore* _store);
-
-
- QPID_BROKER_EXTERN bool isDequeueComplete();
-
- QPID_BROKER_EXTERN void dequeueComplete();
-
- QPID_BROKER_EXTERN void dequeueAsync(PersistableQueue::shared_ptr queue,
- MessageStore* _store);
-
- bool isStoredOnQueue(PersistableQueue::shared_ptr queue);
-
- void addToSyncList(PersistableQueue::shared_ptr queue, MessageStore* _store);
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/PersistableQueue.h b/cpp/src/qpid/broker/PersistableQueue.h
deleted file mode 100644
index 655d26bc74..0000000000
--- a/cpp/src/qpid/broker/PersistableQueue.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef _broker_PersistableQueue_h
-#define _broker_PersistableQueue_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <string>
-#include "qpid/broker/Persistable.h"
-#include "qpid/management/Manageable.h"
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-
-/**
-* Empty class to be used by any module that wanted to set an external per queue store into
-* persistableQueue
-*/
-
-class ExternalQueueStore : public management::Manageable
-{
-public:
- virtual ~ExternalQueueStore() {};
-
-};
-
-
-/**
- * The interface queues must expose to the MessageStore in order to be
- * persistable.
- */
-class PersistableQueue : public Persistable
-{
-public:
- typedef boost::shared_ptr<PersistableQueue> shared_ptr;
-
- virtual const std::string& getName() const = 0;
- virtual ~PersistableQueue() {
- if (externalQueueStore)
- delete externalQueueStore;
- };
-
- virtual void setExternalQueueStore(ExternalQueueStore* inst) = 0;
- virtual void flush() = 0;
-
- inline ExternalQueueStore* getExternalQueueStore() const {return externalQueueStore;};
-
- PersistableQueue():externalQueueStore(NULL){
- };
-
-protected:
- ExternalQueueStore* externalQueueStore;
-
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/PriorityQueue.cpp b/cpp/src/qpid/broker/PriorityQueue.cpp
deleted file mode 100644
index e07e73d323..0000000000
--- a/cpp/src/qpid/broker/PriorityQueue.cpp
+++ /dev/null
@@ -1,212 +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.
- *
- */
-#include "qpid/broker/PriorityQueue.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/framing/reply_exceptions.h"
-#include <cmath>
-
-namespace qpid {
-namespace broker {
-
-PriorityQueue::PriorityQueue(int l) :
- levels(l),
- messages(levels, Deque()),
- frontLevel(0), haveFront(false), cached(false) {}
-
-size_t PriorityQueue::size()
-{
- size_t total(0);
- for (int i = 0; i < levels; ++i) {
- total += messages[i].size();
- }
- return total;
-}
-
-bool PriorityQueue::empty()
-{
- for (int i = 0; i < levels; ++i) {
- if (!messages[i].empty()) return false;
- }
- return true;
-}
-
-void PriorityQueue::reinsert(const QueuedMessage& message)
-{
- uint p = getPriorityLevel(message);
- messages[p].insert(lower_bound(messages[p].begin(), messages[p].end(), message), message);
- clearCache();
-}
-
-bool PriorityQueue::find(const framing::SequenceNumber& position, QueuedMessage& message, bool remove)
-{
- QueuedMessage comp;
- comp.position = position;
- for (int i = 0; i < levels; ++i) {
- if (!messages[i].empty()) {
- unsigned long diff = position.getValue() - messages[i].front().position.getValue();
- long maxEnd = diff < messages[i].size() ? diff : messages[i].size();
- Deque::iterator l = lower_bound(messages[i].begin(),messages[i].begin()+maxEnd,comp);
- if (l != messages[i].end() && l->position == position) {
- message = *l;
- if (remove) {
- messages[i].erase(l);
- clearCache();
- }
- return true;
- }
- }
- }
- return false;
-}
-
-bool PriorityQueue::remove(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- return find(position, message, true);
-}
-
-bool PriorityQueue::find(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- return find(position, message, false);
-}
-
-bool PriorityQueue::next(const framing::SequenceNumber& position, QueuedMessage& message)
-{
- QueuedMessage match;
- match.position = position+1;
- Deque::iterator lowest;
- bool found = false;
- for (int i = 0; i < levels; ++i) {
- Deque::iterator m = lower_bound(messages[i].begin(), messages[i].end(), match);
- if (m != messages[i].end()) {
- if (m->position == match.position) {
- message = *m;
- return true;
- } else if (!found || m->position < lowest->position) {
- lowest = m;
- found = true;
- }
- }
- }
- if (found) {
- message = *lowest;
- }
- return found;
-}
-
-QueuedMessage& PriorityQueue::front()
-{
- if (checkFront()) {
- return messages[frontLevel].front();
- } else {
- throw qpid::framing::InternalErrorException(QPID_MSG("No message available"));
- }
-}
-
-bool PriorityQueue::pop(QueuedMessage& message)
-{
- if (checkFront()) {
- message = messages[frontLevel].front();
- messages[frontLevel].pop_front();
- clearCache();
- return true;
- } else {
- return false;
- }
-}
-
-void PriorityQueue::pop()
-{
- QueuedMessage dummy;
- pop(dummy);
-}
-
-bool PriorityQueue::push(const QueuedMessage& added, QueuedMessage& /*not needed*/)
-{
- messages[getPriorityLevel(added)].push_back(added);
- clearCache();
- return false;//adding a message never causes one to be removed for deque
-}
-
-void PriorityQueue::foreach(Functor f)
-{
- for (int i = 0; i < levels; ++i) {
- std::for_each(messages[i].begin(), messages[i].end(), f);
- }
-}
-
-void PriorityQueue::removeIf(Predicate p)
-{
- for (int priority = 0; priority < levels; ++priority) {
- for (Deque::iterator i = messages[priority].begin(); i != messages[priority].end();) {
- if (p(*i)) {
- i = messages[priority].erase(i);
- clearCache();
- } else {
- ++i;
- }
- }
- }
-}
-
-uint PriorityQueue::getPriorityLevel(const QueuedMessage& m) const
-{
- uint priority = m.payload->getPriority();
- //Use AMQP 0-10 approach to mapping priorities to a fixed level
- //(see rule priority-level-implementation)
- const uint firstLevel = 5 - uint(std::min(5.0, std::ceil((double) levels/2.0)));
- if (priority <= firstLevel) return 0;
- return std::min(priority - firstLevel, (uint)levels-1);
-}
-
-void PriorityQueue::clearCache()
-{
- cached = false;
-}
-
-bool PriorityQueue::findFrontLevel(uint& l, PriorityLevels& m)
-{
- for (int p = levels-1; p >= 0; --p) {
- if (!m[p].empty()) {
- l = p;
- return true;
- }
- }
- return false;
-}
-
-bool PriorityQueue::checkFront()
-{
- if (!cached) {
- haveFront = findFrontLevel(frontLevel, messages);
- cached = true;
- }
- return haveFront;
-}
-
-uint PriorityQueue::getPriority(const QueuedMessage& message)
-{
- const PriorityQueue* queue = dynamic_cast<const PriorityQueue*>(&(message.queue->getMessages()));
- if (queue) return queue->getPriorityLevel(message);
- else return 0;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/PriorityQueue.h b/cpp/src/qpid/broker/PriorityQueue.h
deleted file mode 100644
index 4bf9d26a9d..0000000000
--- a/cpp/src/qpid/broker/PriorityQueue.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef QPID_BROKER_PRIORITYQUEUE_H
-#define QPID_BROKER_PRIORITYQUEUE_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/Messages.h"
-#include "qpid/sys/IntegerTypes.h"
-#include <deque>
-#include <vector>
-
-namespace qpid {
-namespace broker {
-
-/**
- * Basic priority queue with a configurable number of recognised
- * priority levels. This is implemented as a separate deque per
- * priority level. Browsing is FIFO not priority order.
- */
-class PriorityQueue : public Messages
-{
- public:
- PriorityQueue(int levels);
- virtual ~PriorityQueue() {}
- size_t size();
- bool empty();
-
- void reinsert(const QueuedMessage&);
- bool remove(const framing::SequenceNumber&, QueuedMessage&);
- bool find(const framing::SequenceNumber&, QueuedMessage&);
- bool next(const framing::SequenceNumber&, QueuedMessage&);
-
- QueuedMessage& front();
- void pop();
- bool pop(QueuedMessage&);
- bool push(const QueuedMessage& added, QueuedMessage& removed);
-
- void foreach(Functor);
- void removeIf(Predicate);
- static uint getPriority(const QueuedMessage&);
- protected:
- typedef std::deque<QueuedMessage> Deque;
- typedef std::vector<Deque> PriorityLevels;
- virtual bool findFrontLevel(uint& p, PriorityLevels&);
-
- const int levels;
- private:
- PriorityLevels messages;
- uint frontLevel;
- bool haveFront;
- bool cached;
-
- bool find(const framing::SequenceNumber&, QueuedMessage&, bool remove);
- uint getPriorityLevel(const QueuedMessage&) const;
- void clearCache();
- bool checkFront();
-};
-
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_PRIORITYQUEUE_H*/
diff --git a/cpp/src/qpid/broker/Queue.cpp b/cpp/src/qpid/broker/Queue.cpp
deleted file mode 100644
index 8efa8be3dc..0000000000
--- a/cpp/src/qpid/broker/Queue.cpp
+++ /dev/null
@@ -1,1225 +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.
- *
- */
-
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueueEvents.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/broker/Fairshare.h"
-#include "qpid/broker/DeliverableMessage.h"
-#include "qpid/broker/LegacyLVQ.h"
-#include "qpid/broker/MessageDeque.h"
-#include "qpid/broker/MessageMap.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/NullMessageStore.h"
-#include "qpid/broker/QueueRegistry.h"
-#include "qpid/broker/QueueFlowLimit.h"
-#include "qpid/broker/ThresholdAlerts.h"
-
-#include "qpid/StringUtils.h"
-#include "qpid/log/Statement.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/ClusterSafe.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/sys/Time.h"
-#include "qmf/org/apache/qpid/broker/ArgsQueuePurge.h"
-#include "qmf/org/apache/qpid/broker/ArgsQueueReroute.h"
-
-#include <iostream>
-#include <algorithm>
-#include <functional>
-
-#include <boost/bind.hpp>
-#include <boost/intrusive_ptr.hpp>
-
-
-using namespace qpid::broker;
-using namespace qpid::sys;
-using namespace qpid::framing;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using std::for_each;
-using std::mem_fun;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-
-namespace
-{
-const std::string qpidMaxSize("qpid.max_size");
-const std::string qpidMaxCount("qpid.max_count");
-const std::string qpidNoLocal("no-local");
-const std::string qpidTraceIdentity("qpid.trace.id");
-const std::string qpidTraceExclude("qpid.trace.exclude");
-const std::string qpidLastValueQueueKey("qpid.last_value_queue_key");
-const std::string qpidLastValueQueue("qpid.last_value_queue");
-const std::string qpidLastValueQueueNoBrowse("qpid.last_value_queue_no_browse");
-const std::string qpidPersistLastNode("qpid.persist_last_node");
-const std::string qpidVQMatchProperty("qpid.LVQ_key");
-const std::string qpidQueueEventGeneration("qpid.queue_event_generation");
-const std::string qpidAutoDeleteTimeout("qpid.auto_delete_timeout");
-//following feature is not ready for general use as it doesn't handle
-//the case where a message is enqueued on more than one queue well enough:
-const std::string qpidInsertSequenceNumbers("qpid.insert_sequence_numbers");
-
-const int ENQUEUE_ONLY=1;
-const int ENQUEUE_AND_DEQUEUE=2;
-}
-
-Queue::Queue(const string& _name, bool _autodelete,
- MessageStore* const _store,
- const OwnershipToken* const _owner,
- Manageable* parent,
- Broker* b) :
-
- name(_name),
- autodelete(_autodelete),
- store(_store),
- owner(_owner),
- consumerCount(0),
- exclusive(0),
- noLocal(false),
- persistLastNode(false),
- inLastNodeFailure(false),
- messages(new MessageDeque()),
- persistenceId(0),
- policyExceeded(false),
- mgmtObject(0),
- eventMode(0),
- insertSeqNo(0),
- broker(b),
- deleted(false),
- barrier(*this),
- autoDeleteTimeout(0)
-{
- if (parent != 0 && broker != 0) {
- ManagementAgent* agent = broker->getManagementAgent();
-
- if (agent != 0) {
- mgmtObject = new _qmf::Queue(agent, this, parent, _name, _store != 0, _autodelete, _owner != 0);
- agent->addObject(mgmtObject, 0, store != 0);
- }
- }
-}
-
-Queue::~Queue()
-{
- if (mgmtObject != 0)
- mgmtObject->resourceDestroy();
-}
-
-bool isLocalTo(const OwnershipToken* token, boost::intrusive_ptr<Message>& msg)
-{
- return token && token->isLocal(msg->getPublisher());
-}
-
-bool Queue::isLocal(boost::intrusive_ptr<Message>& msg)
-{
- //message is considered local if it was published on the same
- //connection as that of the session which declared this queue
- //exclusive (owner) or which has an exclusive subscription
- //(exclusive)
- return noLocal && (isLocalTo(owner, msg) || isLocalTo(exclusive, msg));
-}
-
-bool Queue::isExcluded(boost::intrusive_ptr<Message>& msg)
-{
- return traceExclude.size() && msg->isExcluded(traceExclude);
-}
-
-void Queue::deliver(boost::intrusive_ptr<Message> msg){
- // Check for deferred delivery in a cluster.
- if (broker && broker->deferDelivery(name, msg))
- return;
- if (msg->isImmediate() && getConsumerCount() == 0) {
- if (alternateExchange) {
- DeliverableMessage deliverable(msg);
- alternateExchange->route(deliverable, msg->getRoutingKey(), msg->getApplicationHeaders());
- }
- } else if (isLocal(msg)) {
- //drop message
- QPID_LOG(info, "Dropping 'local' message from " << getName());
- } else if (isExcluded(msg)) {
- //drop message
- QPID_LOG(info, "Dropping excluded message from " << getName());
- } else {
- enqueue(0, msg);
- push(msg);
- QPID_LOG(debug, "Message " << msg << " enqueued on " << name);
- }
-}
-
-void Queue::recoverPrepared(boost::intrusive_ptr<Message>& msg)
-{
- if (policy.get()) policy->recoverEnqueued(msg);
-}
-
-void Queue::recover(boost::intrusive_ptr<Message>& msg){
- if (policy.get()) policy->recoverEnqueued(msg);
-
- push(msg, true);
- if (store){
- // setup synclist for recovered messages, so they don't get re-stored on lastNodeFailure
- msg->addToSyncList(shared_from_this(), store);
- }
-
- if (store && (!msg->isContentLoaded() || msg->checkContentReleasable())) {
- //content has not been loaded, need to ensure that lazy loading mode is set:
- //TODO: find a nicer way to do this
- msg->releaseContent(store);
- // NOTE: The log message in this section are used for flow-to-disk testing (which checks the log for the
- // presence of this message). Do not change this without also checking these tests.
- QPID_LOG(debug, "Message id=\"" << msg->getProperties<MessageProperties>()->getMessageId() << "\"; pid=0x" <<
- std::hex << msg->getPersistenceId() << std::dec << ": Content released after recovery");
- }
-}
-
-void Queue::process(boost::intrusive_ptr<Message>& msg){
- push(msg);
- if (mgmtObject != 0){
- mgmtObject->inc_msgTxnEnqueues ();
- mgmtObject->inc_byteTxnEnqueues (msg->contentSize ());
- }
-}
-
-void Queue::requeue(const QueuedMessage& msg){
- assertClusterSafe();
- QueueListeners::NotificationSet copy;
- {
- Mutex::ScopedLock locker(messageLock);
- if (!isEnqueued(msg)) return;
- messages->reinsert(msg);
- listeners.populate(copy);
-
- // for persistLastNode - don't force a message twice to disk, but force it if no force before
- if(inLastNodeFailure && persistLastNode && !msg.payload->isStoredOnQueue(shared_from_this())) {
- msg.payload->forcePersistent();
- if (msg.payload->isForcedPersistent() ){
- boost::intrusive_ptr<Message> payload = msg.payload;
- enqueue(0, payload);
- }
- }
- }
- copy.notify();
-}
-
-bool Queue::acquireMessageAt(const SequenceNumber& position, QueuedMessage& message)
-{
- Mutex::ScopedLock locker(messageLock);
- assertClusterSafe();
- QPID_LOG(debug, "Attempting to acquire message at " << position);
- if (messages->remove(position, message)) {
- QPID_LOG(debug, "Acquired message at " << position << " from " << name);
- return true;
- } else {
- QPID_LOG(debug, "Could not acquire message at " << position << " from " << name << "; no message at that position");
- return false;
- }
-}
-
-bool Queue::acquire(const QueuedMessage& msg) {
- QueuedMessage copy = msg;
- return acquireMessageAt(msg.position, copy);
-}
-
-void Queue::notifyListener()
-{
- assertClusterSafe();
- QueueListeners::NotificationSet set;
- {
- Mutex::ScopedLock locker(messageLock);
- if (messages->size()) {
- listeners.populate(set);
- }
- }
- set.notify();
-}
-
-bool Queue::getNextMessage(QueuedMessage& m, Consumer::shared_ptr c)
-{
- checkNotDeleted();
- if (c->preAcquires()) {
- switch (consumeNextMessage(m, c)) {
- case CONSUMED:
- return true;
- case CANT_CONSUME:
- notifyListener();//let someone else try
- case NO_MESSAGES:
- default:
- return false;
- }
- } else {
- return browseNextMessage(m, c);
- }
-}
-
-Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_ptr c)
-{
- while (true) {
- Mutex::ScopedLock locker(messageLock);
- if (messages->empty()) {
- QPID_LOG(debug, "No messages to dispatch on queue '" << name << "'");
- listeners.addListener(c);
- return NO_MESSAGES;
- } else {
- QueuedMessage msg = messages->front();
- if (msg.payload->hasExpired()) {
- QPID_LOG(debug, "Message expired from queue '" << name << "'");
- popAndDequeue();
- continue;
- }
-
- if (c->filter(msg.payload)) {
- if (c->accept(msg.payload)) {
- m = msg;
- pop();
- return CONSUMED;
- } else {
- //message(s) are available but consumer hasn't got enough credit
- QPID_LOG(debug, "Consumer can't currently accept message from '" << name << "'");
- return CANT_CONSUME;
- }
- } else {
- //consumer will never want this message
- QPID_LOG(debug, "Consumer doesn't want message from '" << name << "'");
- return CANT_CONSUME;
- }
- }
- }
-}
-
-
-bool Queue::browseNextMessage(QueuedMessage& m, Consumer::shared_ptr c)
-{
- QueuedMessage msg(this);
- while (seek(msg, c)) {
- if (c->filter(msg.payload) && !msg.payload->hasExpired()) {
- if (c->accept(msg.payload)) {
- //consumer wants the message
- c->position = msg.position;
- m = msg;
- return true;
- } else {
- //browser hasn't got enough credit for the message
- QPID_LOG(debug, "Browser can't currently accept message from '" << name << "'");
- return false;
- }
- } else {
- //consumer will never want this message, continue seeking
- c->position = msg.position;
- QPID_LOG(debug, "Browser skipping message from '" << name << "'");
- }
- }
- return false;
-}
-
-void Queue::removeListener(Consumer::shared_ptr c)
-{
- QueueListeners::NotificationSet set;
- {
- Mutex::ScopedLock locker(messageLock);
- listeners.removeListener(c);
- if (messages->size()) {
- listeners.populate(set);
- }
- }
- set.notify();
-}
-
-bool Queue::dispatch(Consumer::shared_ptr c)
-{
- QueuedMessage msg(this);
- if (getNextMessage(msg, c)) {
- c->deliver(msg);
- return true;
- } else {
- return false;
- }
-}
-
-// Find the next message
-bool Queue::seek(QueuedMessage& msg, Consumer::shared_ptr c) {
- Mutex::ScopedLock locker(messageLock);
- if (messages->next(c->position, msg)) {
- return true;
- } else {
- listeners.addListener(c);
- return false;
- }
-}
-
-QueuedMessage Queue::find(SequenceNumber pos) const {
-
- Mutex::ScopedLock locker(messageLock);
- QueuedMessage msg;
- messages->find(pos, msg);
- return msg;
-}
-
-void Queue::consume(Consumer::shared_ptr c, bool requestExclusive){
- assertClusterSafe();
- Mutex::ScopedLock locker(consumerLock);
- if(exclusive) {
- throw ResourceLockedException(
- QPID_MSG("Queue " << getName() << " has an exclusive consumer. No more consumers allowed."));
- } else if(requestExclusive) {
- if(consumerCount) {
- throw ResourceLockedException(
- QPID_MSG("Queue " << getName() << " already has consumers. Exclusive access denied."));
- } else {
- exclusive = c->getSession();
- }
- }
- consumerCount++;
- if (mgmtObject != 0)
- mgmtObject->inc_consumerCount ();
- //reset auto deletion timer if necessary
- if (autoDeleteTimeout && autoDeleteTask) {
- autoDeleteTask->cancel();
- }
-}
-
-void Queue::cancel(Consumer::shared_ptr c){
- removeListener(c);
- Mutex::ScopedLock locker(consumerLock);
- consumerCount--;
- if(exclusive) exclusive = 0;
- if (mgmtObject != 0)
- mgmtObject->dec_consumerCount ();
-}
-
-QueuedMessage Queue::get(){
- Mutex::ScopedLock locker(messageLock);
- QueuedMessage msg(this);
- messages->pop(msg);
- return msg;
-}
-
-bool collect_if_expired(std::deque<QueuedMessage>& expired, QueuedMessage& message)
-{
- if (message.payload->hasExpired()) {
- expired.push_back(message);
- return true;
- } else {
- return false;
- }
-}
-
-void Queue::purgeExpired()
-{
- //As expired messages are discarded during dequeue also, only
- //bother explicitly expiring if the rate of dequeues since last
- //attempt is less than one per second.
-
- if (dequeueTracker.sampleRatePerSecond() < 1) {
- std::deque<QueuedMessage> expired;
- {
- Mutex::ScopedLock locker(messageLock);
- messages->removeIf(boost::bind(&collect_if_expired, expired, _1));
- }
- for_each(expired.begin(), expired.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
- }
-}
-
-/**
- * purge - for purging all or some messages on a queue
- * depending on the purge_request
- *
- * purge_request == 0 then purge all messages
- * == N then purge N messages from queue
- * Sometimes purge_request == 1 to unblock the top of queue
- *
- * The dest exchange may be supplied to re-route messages through the exchange.
- * It is safe to re-route messages such that they arrive back on the same queue,
- * even if the queue is ordered by priority.
- */
-uint32_t Queue::purge(const uint32_t purge_request, boost::shared_ptr<Exchange> dest)
-{
- Mutex::ScopedLock locker(messageLock);
- uint32_t purge_count = purge_request; // only comes into play if >0
- std::deque<DeliverableMessage> rerouteQueue;
-
- uint32_t count = 0;
- // Either purge them all or just the some (purge_count) while the queue isn't empty.
- while((!purge_request || purge_count--) && !messages->empty()) {
- if (dest.get()) {
- //
- // If there is a destination exchange, stage the messages onto a reroute queue
- // so they don't wind up getting purged more than once.
- //
- DeliverableMessage msg(messages->front().payload);
- rerouteQueue.push_back(msg);
- }
- popAndDequeue();
- count++;
- }
-
- //
- // Re-route purged messages into the destination exchange. Note that there's no need
- // to test dest.get() here because if it is NULL, the rerouteQueue will be empty.
- //
- while (!rerouteQueue.empty()) {
- DeliverableMessage msg(rerouteQueue.front());
- rerouteQueue.pop_front();
- dest->routeWithAlternate(msg);
- }
-
- return count;
-}
-
-uint32_t Queue::move(const Queue::shared_ptr destq, uint32_t qty) {
- Mutex::ScopedLock locker(messageLock);
- uint32_t move_count = qty; // only comes into play if qty >0
- uint32_t count = 0; // count how many were moved for returning
-
- while((!qty || move_count--) && !messages->empty()) {
- QueuedMessage qmsg = messages->front();
- boost::intrusive_ptr<Message> msg = qmsg.payload;
- destq->deliver(msg); // deliver message to the destination queue
- pop();
- dequeue(0, qmsg);
- count++;
- }
- return count;
-}
-
-void Queue::pop()
-{
- assertClusterSafe();
- messages->pop();
- ++dequeueTracker;
-}
-
-void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
- assertClusterSafe();
- QueueListeners::NotificationSet copy;
- QueuedMessage removed;
- bool dequeueRequired = false;
- {
- Mutex::ScopedLock locker(messageLock);
- QueuedMessage qm(this, msg, ++sequence);
- if (insertSeqNo) msg->getOrInsertHeaders().setInt64(seqNoKey, sequence);
-
- dequeueRequired = messages->push(qm, removed);
- listeners.populate(copy);
- enqueued(qm);
- }
- copy.notify();
- if (dequeueRequired) {
- if (isRecovery) {
- //can't issue new requests for the store until
- //recovery is complete
- pendingDequeues.push_back(removed);
- } else {
- dequeue(0, removed);
- }
- }
-}
-
-void isEnqueueComplete(uint32_t* result, const QueuedMessage& message)
-{
- if (message.payload->isIngressComplete()) (*result)++;
-}
-
-/** function only provided for unit tests, or code not in critical message path */
-uint32_t Queue::getEnqueueCompleteMessageCount() const
-{
- Mutex::ScopedLock locker(messageLock);
- uint32_t count = 0;
- messages->foreach(boost::bind(&isEnqueueComplete, &count, _1));
- return count;
-}
-
-uint32_t Queue::getMessageCount() const
-{
- Mutex::ScopedLock locker(messageLock);
- return messages->size();
-}
-
-uint32_t Queue::getConsumerCount() const
-{
- Mutex::ScopedLock locker(consumerLock);
- return consumerCount;
-}
-
-bool Queue::canAutoDelete() const
-{
- Mutex::ScopedLock locker(consumerLock);
- return autodelete && !consumerCount && !owner;
-}
-
-void Queue::clearLastNodeFailure()
-{
- inLastNodeFailure = false;
-}
-
-void Queue::forcePersistent(QueuedMessage& message)
-{
- if(!message.payload->isStoredOnQueue(shared_from_this())) {
- message.payload->forcePersistent();
- if (message.payload->isForcedPersistent() ){
- enqueue(0, message.payload);
- }
- }
-}
-
-void Queue::setLastNodeFailure()
-{
- if (persistLastNode){
- Mutex::ScopedLock locker(messageLock);
- try {
- messages->foreach(boost::bind(&Queue::forcePersistent, this, _1));
- } catch (const std::exception& e) {
- // Could not go into last node standing (for example journal not large enough)
- QPID_LOG(error, "Unable to fail to last node standing for queue: " << name << " : " << e.what());
- }
- inLastNodeFailure = true;
- }
-}
-
-
-// return true if store exists,
-bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg, bool suppressPolicyCheck)
-{
- ScopedUse u(barrier);
- if (!u.acquired) return false;
-
- if (policy.get() && !suppressPolicyCheck) {
- std::deque<QueuedMessage> dequeues;
- {
- Mutex::ScopedLock locker(messageLock);
- policy->tryEnqueue(msg);
- policy->getPendingDequeues(dequeues);
- }
- //depending on policy, may have some dequeues that need to performed without holding the lock
- for_each(dequeues.begin(), dequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
- }
-
- if (inLastNodeFailure && persistLastNode){
- msg->forcePersistent();
- }
-
- if (traceId.size()) {
- //copy on write: take deep copy of message before modifying it
- //as the frames may already be available for delivery on other
- //threads
- boost::intrusive_ptr<Message> copy(new Message(*msg));
- msg = copy;
- msg->addTraceId(traceId);
- }
-
- if ((msg->isPersistent() || msg->checkContentReleasable()) && store) {
- // mark the message as being enqueued - the store MUST CALL msg->enqueueComplete()
- // when it considers the message stored.
- msg->enqueueAsync(shared_from_this(), store);
- boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg);
- store->enqueue(ctxt, pmsg, *this);
- return true;
- }
- if (!store) {
- //Messages enqueued on a transient queue should be prevented
- //from having their content released as it may not be
- //recoverable by these queue for delivery
- msg->blockContentRelease();
- }
- return false;
-}
-
-void Queue::enqueueAborted(boost::intrusive_ptr<Message> msg)
-{
- Mutex::ScopedLock locker(messageLock);
- if (policy.get()) policy->enqueueAborted(msg);
-}
-
-// return true if store exists,
-bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
-{
- ScopedUse u(barrier);
- if (!u.acquired) return false;
-
- {
- Mutex::ScopedLock locker(messageLock);
- if (!isEnqueued(msg)) return false;
- if (!ctxt) {
- dequeued(msg);
- }
- }
- // This check prevents messages which have been forced persistent on one queue from dequeuing
- // from another on which no forcing has taken place and thus causing a store error.
- bool fp = msg.payload->isForcedPersistent();
- if (!fp || (fp && msg.payload->isStoredOnQueue(shared_from_this()))) {
- if ((msg.payload->isPersistent() || msg.payload->checkContentReleasable()) && store) {
- msg.payload->dequeueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue
- boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg.payload);
- store->dequeue(ctxt, pmsg, *this);
- return true;
- }
- }
- return false;
-}
-
-void Queue::dequeueCommitted(const QueuedMessage& msg)
-{
- Mutex::ScopedLock locker(messageLock);
- dequeued(msg);
- if (mgmtObject != 0) {
- mgmtObject->inc_msgTxnDequeues();
- mgmtObject->inc_byteTxnDequeues(msg.payload->contentSize());
- }
-}
-
-/**
- * Removes a message from the in-memory delivery queue as well
- * dequeing it from the logical (and persistent if applicable) queue
- */
-void Queue::popAndDequeue()
-{
- QueuedMessage msg = messages->front();
- pop();
- dequeue(0, msg);
-}
-
-/**
- * Updates policy and management when a message has been dequeued,
- * expects messageLock to be held
- */
-void Queue::dequeued(const QueuedMessage& msg)
-{
- if (policy.get()) policy->dequeued(msg);
- mgntDeqStats(msg.payload);
- for (Observers::const_iterator i = observers.begin(); i != observers.end(); ++i) {
- try{
- (*i)->dequeued(msg);
- } catch (const std::exception& e) {
- QPID_LOG(warning, "Exception on notification of dequeue for queue " << getName() << ": " << e.what());
- }
- }
-}
-
-
-void Queue::create(const FieldTable& _settings)
-{
- settings = _settings;
- if (store) {
- store->create(*this, _settings);
- }
- configureImpl(_settings);
-}
-
-
-int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::string& key)
-{
- qpid::framing::FieldTable::ValuePtr v = settings.get(key);
- if (!v) {
- return 0;
- } else if (v->convertsTo<int>()) {
- return v->get<int>();
- } else if (v->convertsTo<std::string>()){
- std::string s = v->get<std::string>();
- try {
- return boost::lexical_cast<int>(s);
- } catch(const boost::bad_lexical_cast&) {
- QPID_LOG(warning, "Ignoring invalid integer value for " << key << ": " << s);
- return 0;
- }
- } else {
- QPID_LOG(warning, "Ignoring invalid integer value for " << key << ": " << *v);
- return 0;
- }
-}
-
-void Queue::configure(const FieldTable& _settings)
-{
- settings = _settings;
- configureImpl(settings);
-}
-
-void Queue::configureImpl(const FieldTable& _settings)
-{
- eventMode = _settings.getAsInt(qpidQueueEventGeneration);
- if (eventMode && broker) {
- broker->getQueueEvents().observe(*this, eventMode == ENQUEUE_ONLY);
- }
-
- if (QueuePolicy::getType(_settings) == QueuePolicy::FLOW_TO_DISK &&
- (!store || NullMessageStore::isNullStore(store) || (broker && !(broker->getQueueEvents().isSync())) )) {
- if ( NullMessageStore::isNullStore(store)) {
- QPID_LOG(warning, "Flow to disk not valid for non-persisted queue:" << getName());
- } else if (broker && !(broker->getQueueEvents().isSync()) ) {
- QPID_LOG(warning, "Flow to disk not valid with async Queue Events:" << getName());
- }
- FieldTable copy(_settings);
- copy.erase(QueuePolicy::typeKey);
- setPolicy(QueuePolicy::createQueuePolicy(getName(), copy));
- } else {
- setPolicy(QueuePolicy::createQueuePolicy(getName(), _settings));
- }
- if (broker && broker->getManagementAgent()) {
- ThresholdAlerts::observe(*this, *(broker->getManagementAgent()), _settings, broker->getOptions().queueThresholdEventRatio);
- }
-
- //set this regardless of owner to allow use of no-local with exclusive consumers also
- noLocal = _settings.get(qpidNoLocal);
- QPID_LOG(debug, "Configured queue " << getName() << " with no-local=" << noLocal);
-
- std::string lvqKey = _settings.getAsString(qpidLastValueQueueKey);
- if (lvqKey.size()) {
- QPID_LOG(debug, "Configured queue " << getName() << " as Last Value Queue with key " << lvqKey);
- messages = std::auto_ptr<Messages>(new MessageMap(lvqKey));
- } else if (_settings.get(qpidLastValueQueueNoBrowse)) {
- QPID_LOG(debug, "Configured queue " << getName() << " as Legacy Last Value Queue with 'no-browse' on");
- messages = LegacyLVQ::updateOrReplace(messages, qpidVQMatchProperty, true, broker);
- } else if (_settings.get(qpidLastValueQueue)) {
- QPID_LOG(debug, "Configured queue " << getName() << " as Legacy Last Value Queue");
- messages = LegacyLVQ::updateOrReplace(messages, qpidVQMatchProperty, false, broker);
- } else {
- std::auto_ptr<Messages> m = Fairshare::create(_settings);
- if (m.get()) {
- messages = m;
- QPID_LOG(debug, "Configured queue " << getName() << " as priority queue.");
- }
- }
-
- persistLastNode= _settings.get(qpidPersistLastNode);
- if (persistLastNode) QPID_LOG(debug, "Configured queue to Persist data if cluster fails to one node for: " << getName());
-
- traceId = _settings.getAsString(qpidTraceIdentity);
- std::string excludeList = _settings.getAsString(qpidTraceExclude);
- if (excludeList.size()) {
- split(traceExclude, excludeList, ", ");
- }
- QPID_LOG(debug, "Configured queue " << getName() << " with qpid.trace.id='" << traceId
- << "' and qpid.trace.exclude='"<< excludeList << "' i.e. " << traceExclude.size() << " elements");
-
- FieldTable::ValuePtr p =_settings.get(qpidInsertSequenceNumbers);
- if (p && p->convertsTo<std::string>()) insertSequenceNumbers(p->get<std::string>());
-
- autoDeleteTimeout = getIntegerSetting(_settings, qpidAutoDeleteTimeout);
- if (autoDeleteTimeout)
- QPID_LOG(debug, "Configured queue " << getName() << " with qpid.auto_delete_timeout=" << autoDeleteTimeout);
-
- if (mgmtObject != 0) {
- mgmtObject->set_arguments(ManagementAgent::toMap(_settings));
- }
-
- QueueFlowLimit::observe(*this, _settings);
-}
-
-void Queue::destroyed()
-{
- unbind(broker->getExchanges());
- if (alternateExchange.get()) {
- Mutex::ScopedLock locker(messageLock);
- while(!messages->empty()){
- DeliverableMessage msg(messages->front().payload);
- alternateExchange->routeWithAlternate(msg);
- popAndDequeue();
- }
- alternateExchange->decAlternateUsers();
- }
-
- if (store) {
- barrier.destroy();
- store->flush(*this);
- store->destroy(*this);
- store = 0;//ensure we make no more calls to the store for this queue
- }
- if (autoDeleteTask) autoDeleteTask = boost::intrusive_ptr<TimerTask>();
- notifyDeleted();
-}
-
-void Queue::notifyDeleted()
-{
- QueueListeners::ListenerSet set;
- {
- Mutex::ScopedLock locker(messageLock);
- listeners.snapshot(set);
- deleted = true;
- }
- set.notifyAll();
-}
-
-void Queue::bound(const string& exchange, const string& key,
- const FieldTable& args)
-{
- bindings.add(exchange, key, args);
-}
-
-void Queue::unbind(ExchangeRegistry& exchanges)
-{
- bindings.unbind(exchanges, shared_from_this());
-}
-
-void Queue::setPolicy(std::auto_ptr<QueuePolicy> _policy)
-{
- policy = _policy;
-}
-
-const QueuePolicy* Queue::getPolicy()
-{
- return policy.get();
-}
-
-uint64_t Queue::getPersistenceId() const
-{
- return persistenceId;
-}
-
-void Queue::setPersistenceId(uint64_t _persistenceId) const
-{
- if (mgmtObject != 0 && persistenceId == 0 && externalQueueStore)
- {
- ManagementObject* childObj = externalQueueStore->GetManagementObject();
- if (childObj != 0)
- childObj->setReference(mgmtObject->getObjectId());
- }
- persistenceId = _persistenceId;
-}
-
-void Queue::encode(Buffer& buffer) const
-{
- buffer.putShortString(name);
- buffer.put(settings);
- if (policy.get()) {
- buffer.put(*policy);
- }
- buffer.putShortString(alternateExchange.get() ? alternateExchange->getName() : std::string(""));
-}
-
-uint32_t Queue::encodedSize() const
-{
- return name.size() + 1/*short string size octet*/
- + (alternateExchange.get() ? alternateExchange->getName().size() : 0) + 1 /* short string */
- + settings.encodedSize()
- + (policy.get() ? (*policy).encodedSize() : 0);
-}
-
-Queue::shared_ptr Queue::restore( QueueRegistry& queues, Buffer& buffer )
-{
- string name;
- buffer.getShortString(name);
- FieldTable settings;
- buffer.get(settings);
- boost::shared_ptr<Exchange> alternate;
- std::pair<Queue::shared_ptr, bool> result = queues.declare(name, true, false, 0, alternate, settings, true);
- if (result.first->policy.get() && buffer.available() >= result.first->policy->encodedSize()) {
- buffer.get ( *(result.first->policy) );
- }
- if (buffer.available()) {
- string altExch;
- buffer.getShortString(altExch);
- result.first->alternateExchangeName.assign(altExch);
- }
-
- return result.first;
-}
-
-
-void Queue::setAlternateExchange(boost::shared_ptr<Exchange> exchange)
-{
- alternateExchange = exchange;
- if (mgmtObject) {
- if (exchange.get() != 0)
- mgmtObject->set_altExchange(exchange->GetManagementObject()->getObjectId());
- else
- mgmtObject->clr_altExchange();
- }
-}
-
-boost::shared_ptr<Exchange> Queue::getAlternateExchange()
-{
- return alternateExchange;
-}
-
-void tryAutoDeleteImpl(Broker& broker, Queue::shared_ptr queue)
-{
- if (broker.getQueues().destroyIf(queue->getName(),
- boost::bind(boost::mem_fn(&Queue::canAutoDelete), queue))) {
- QPID_LOG(debug, "Auto-deleting " << queue->getName());
- queue->destroyed();
- }
-}
-
-struct AutoDeleteTask : qpid::sys::TimerTask
-{
- Broker& broker;
- Queue::shared_ptr queue;
-
- AutoDeleteTask(Broker& b, Queue::shared_ptr q, AbsTime fireTime)
- : qpid::sys::TimerTask(fireTime, "DelayedAutoDeletion"), broker(b), queue(q) {}
-
- void fire()
- {
- //need to detect case where queue was used after the task was
- //created, but then became unused again before the task fired;
- //in this case ignore this request as there will have already
- //been a later task added
- tryAutoDeleteImpl(broker, queue);
- }
-};
-
-void Queue::tryAutoDelete(Broker& broker, Queue::shared_ptr queue)
-{
- if (queue->autoDeleteTimeout && queue->canAutoDelete()) {
- AbsTime time(now(), Duration(queue->autoDeleteTimeout * TIME_SEC));
- queue->autoDeleteTask = boost::intrusive_ptr<qpid::sys::TimerTask>(new AutoDeleteTask(broker, queue, time));
- broker.getClusterTimer().add(queue->autoDeleteTask);
- QPID_LOG(debug, "Timed auto-delete for " << queue->getName() << " initiated");
- } else {
- tryAutoDeleteImpl(broker, queue);
- }
-}
-
-bool Queue::isExclusiveOwner(const OwnershipToken* const o) const
-{
- Mutex::ScopedLock locker(ownershipLock);
- return o == owner;
-}
-
-void Queue::releaseExclusiveOwnership()
-{
- Mutex::ScopedLock locker(ownershipLock);
- owner = 0;
-}
-
-bool Queue::setExclusiveOwner(const OwnershipToken* const o)
-{
- //reset auto deletion timer if necessary
- if (autoDeleteTimeout && autoDeleteTask) {
- autoDeleteTask->cancel();
- }
- Mutex::ScopedLock locker(ownershipLock);
- if (owner) {
- return false;
- } else {
- owner = o;
- return true;
- }
-}
-
-bool Queue::hasExclusiveOwner() const
-{
- Mutex::ScopedLock locker(ownershipLock);
- return owner != 0;
-}
-
-bool Queue::hasExclusiveConsumer() const
-{
- return exclusive;
-}
-
-void Queue::setExternalQueueStore(ExternalQueueStore* inst) {
- if (externalQueueStore!=inst && externalQueueStore)
- delete externalQueueStore;
- externalQueueStore = inst;
-
- if (inst) {
- ManagementObject* childObj = inst->GetManagementObject();
- if (childObj != 0 && mgmtObject != 0)
- childObj->setReference(mgmtObject->getObjectId());
- }
-}
-
-ManagementObject* Queue::GetManagementObject (void) const
-{
- return (ManagementObject*) mgmtObject;
-}
-
-Manageable::status_t Queue::ManagementMethod (uint32_t methodId, Args& args, string& etext)
-{
- Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD;
-
- QPID_LOG (debug, "Queue::ManagementMethod [id=" << methodId << "]");
-
- switch (methodId) {
- case _qmf::Queue::METHOD_PURGE :
- {
- _qmf::ArgsQueuePurge& purgeArgs = (_qmf::ArgsQueuePurge&) args;
- purge(purgeArgs.i_request);
- status = Manageable::STATUS_OK;
- }
- break;
-
- case _qmf::Queue::METHOD_REROUTE :
- {
- _qmf::ArgsQueueReroute& rerouteArgs = (_qmf::ArgsQueueReroute&) args;
- boost::shared_ptr<Exchange> dest;
- if (rerouteArgs.i_useAltExchange)
- dest = alternateExchange;
- else {
- try {
- dest = broker->getExchanges().get(rerouteArgs.i_exchange);
- } catch(const std::exception&) {
- status = Manageable::STATUS_PARAMETER_INVALID;
- etext = "Exchange not found";
- break;
- }
- }
-
- purge(rerouteArgs.i_request, dest);
- status = Manageable::STATUS_OK;
- }
- break;
- }
-
- return status;
-}
-
-void Queue::setPosition(SequenceNumber n) {
- Mutex::ScopedLock locker(messageLock);
- sequence = n;
-}
-
-SequenceNumber Queue::getPosition() {
- return sequence;
-}
-
-int Queue::getEventMode() { return eventMode; }
-
-void Queue::recoveryComplete(ExchangeRegistry& exchanges)
-{
- // set the alternate exchange
- if (!alternateExchangeName.empty()) {
- try {
- Exchange::shared_ptr ae = exchanges.get(alternateExchangeName);
- setAlternateExchange(ae);
- } catch (const NotFoundException&) {
- QPID_LOG(warning, "Could not set alternate exchange \"" << alternateExchangeName << "\" on queue \"" << name << "\": exchange does not exist.");
- }
- }
- //process any pending dequeues
- for_each(pendingDequeues.begin(), pendingDequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
- pendingDequeues.clear();
-}
-
-void Queue::insertSequenceNumbers(const std::string& key)
-{
- seqNoKey = key;
- insertSeqNo = !seqNoKey.empty();
- QPID_LOG(debug, "Inserting sequence numbers as " << key);
-}
-
-void Queue::enqueued(const QueuedMessage& m)
-{
- for (Observers::iterator i = observers.begin(); i != observers.end(); ++i) {
- try {
- (*i)->enqueued(m);
- } catch (const std::exception& e) {
- QPID_LOG(warning, "Exception on notification of enqueue for queue " << getName() << ": " << e.what());
- }
- }
- if (policy.get()) {
- policy->enqueued(m);
- }
- mgntEnqStats(m.payload);
-}
-
-void Queue::updateEnqueued(const QueuedMessage& m)
-{
- if (m.payload) {
- boost::intrusive_ptr<Message> payload = m.payload;
- enqueue ( 0, payload, true );
- if (policy.get()) {
- policy->recoverEnqueued(payload);
- }
- enqueued(m);
- } else {
- QPID_LOG(warning, "Queue informed of enqueued message that has no payload");
- }
-}
-
-bool Queue::isEnqueued(const QueuedMessage& msg)
-{
- return !policy.get() || policy->isEnqueued(msg);
-}
-
-QueueListeners& Queue::getListeners() { return listeners; }
-Messages& Queue::getMessages() { return *messages; }
-const Messages& Queue::getMessages() const { return *messages; }
-
-void Queue::checkNotDeleted()
-{
- if (deleted) {
- throw ResourceDeletedException(QPID_MSG("Queue " << getName() << " has been deleted."));
- }
-}
-
-void Queue::addObserver(boost::shared_ptr<QueueObserver> observer)
-{
- observers.insert(observer);
-}
-
-void Queue::flush()
-{
- ScopedUse u(barrier);
- if (u.acquired && store) store->flush(*this);
-}
-
-
-bool Queue::bind(boost::shared_ptr<Exchange> exchange, const std::string& key,
- const qpid::framing::FieldTable& arguments)
-{
- if (exchange->bind(shared_from_this(), key, &arguments)) {
- bound(exchange->getName(), key, arguments);
- if (exchange->isDurable() && isDurable()) {
- store->bind(*exchange, *this, key, arguments);
- }
- return true;
- } else {
- return false;
- }
-}
-
-
-const Broker* Queue::getBroker()
-{
- return broker;
-}
-
-
-Queue::UsageBarrier::UsageBarrier(Queue& q) : parent(q), count(0) {}
-
-bool Queue::UsageBarrier::acquire()
-{
- Monitor::ScopedLock l(parent.messageLock);
- if (parent.deleted) {
- return false;
- } else {
- ++count;
- return true;
- }
-}
-
-void Queue::UsageBarrier::release()
-{
- Monitor::ScopedLock l(parent.messageLock);
- if (--count == 0) parent.messageLock.notifyAll();
-}
-
-void Queue::UsageBarrier::destroy()
-{
- Monitor::ScopedLock l(parent.messageLock);
- parent.deleted = true;
- while (count) parent.messageLock.wait();
-}
diff --git a/cpp/src/qpid/broker/Queue.h b/cpp/src/qpid/broker/Queue.h
deleted file mode 100644
index c4f1bcc07e..0000000000
--- a/cpp/src/qpid/broker/Queue.h
+++ /dev/null
@@ -1,390 +0,0 @@
-#ifndef _broker_Queue_h
-#define _broker_Queue_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/OwnershipToken.h"
-#include "qpid/broker/Consumer.h"
-#include "qpid/broker/Message.h"
-#include "qpid/broker/Messages.h"
-#include "qpid/broker/PersistableQueue.h"
-#include "qpid/broker/QueuePolicy.h"
-#include "qpid/broker/QueueBindings.h"
-#include "qpid/broker/QueueListeners.h"
-#include "qpid/broker/QueueObserver.h"
-#include "qpid/broker/RateTracker.h"
-
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/sys/Timer.h"
-#include "qpid/management/Manageable.h"
-#include "qmf/org/apache/qpid/broker/Queue.h"
-#include "qpid/framing/amqp_types.h"
-
-#include <boost/shared_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-#include <list>
-#include <vector>
-#include <memory>
-#include <deque>
-#include <set>
-#include <algorithm>
-
-namespace qpid {
-namespace broker {
-class Broker;
-class MessageStore;
-class QueueEvents;
-class QueueRegistry;
-class TransactionContext;
-class Exchange;
-
-/**
- * The brokers representation of an amqp queue. Messages are
- * delivered to a queue from where they can be dispatched to
- * registered consumers or be stored until dequeued or until one
- * or more consumers registers.
- */
-class Queue : public boost::enable_shared_from_this<Queue>,
- public PersistableQueue, public management::Manageable {
-
- struct UsageBarrier
- {
- Queue& parent;
- uint count;
-
- UsageBarrier(Queue&);
- bool acquire();
- void release();
- void destroy();
- };
-
- struct ScopedUse
- {
- UsageBarrier& barrier;
- const bool acquired;
- ScopedUse(UsageBarrier& b) : barrier(b), acquired(barrier.acquire()) {}
- ~ScopedUse() { if (acquired) barrier.release(); }
- };
-
- typedef std::set< boost::shared_ptr<QueueObserver> > Observers;
- enum ConsumeCode {NO_MESSAGES=0, CANT_CONSUME=1, CONSUMED=2};
-
-
- const std::string name;
- const bool autodelete;
- MessageStore* store;
- const OwnershipToken* owner;
- uint32_t consumerCount;
- OwnershipToken* exclusive;
- bool noLocal;
- bool persistLastNode;
- bool inLastNodeFailure;
- std::string traceId;
- std::vector<std::string> traceExclude;
- QueueListeners listeners;
- std::auto_ptr<Messages> messages;
- std::deque<QueuedMessage> pendingDequeues;//used to avoid dequeuing during recovery
- mutable qpid::sys::Mutex consumerLock;
- mutable qpid::sys::Monitor messageLock;
- mutable qpid::sys::Mutex ownershipLock;
- mutable uint64_t persistenceId;
- framing::FieldTable settings;
- std::auto_ptr<QueuePolicy> policy;
- bool policyExceeded;
- QueueBindings bindings;
- std::string alternateExchangeName;
- boost::shared_ptr<Exchange> alternateExchange;
- framing::SequenceNumber sequence;
- qmf::org::apache::qpid::broker::Queue* mgmtObject;
- RateTracker dequeueTracker;
- int eventMode;
- Observers observers;
- bool insertSeqNo;
- std::string seqNoKey;
- Broker* broker;
- bool deleted;
- UsageBarrier barrier;
- int autoDeleteTimeout;
- boost::intrusive_ptr<qpid::sys::TimerTask> autoDeleteTask;
-
- void push(boost::intrusive_ptr<Message>& msg, bool isRecovery=false);
- void setPolicy(std::auto_ptr<QueuePolicy> policy);
- bool seek(QueuedMessage& msg, Consumer::shared_ptr position);
- bool getNextMessage(QueuedMessage& msg, Consumer::shared_ptr c);
- ConsumeCode consumeNextMessage(QueuedMessage& msg, Consumer::shared_ptr c);
- bool browseNextMessage(QueuedMessage& msg, Consumer::shared_ptr c);
- void notifyListener();
-
- void removeListener(Consumer::shared_ptr);
-
- bool isExcluded(boost::intrusive_ptr<Message>& msg);
-
- void enqueued(const QueuedMessage& msg);
- void dequeued(const QueuedMessage& msg);
- void pop();
- void popAndDequeue();
- QueuedMessage getFront();
- void forcePersistent(QueuedMessage& msg);
- int getEventMode();
- void configureImpl(const qpid::framing::FieldTable& settings);
-
- inline void mgntEnqStats(const boost::intrusive_ptr<Message>& msg)
- {
- if (mgmtObject != 0) {
- mgmtObject->inc_msgTotalEnqueues ();
- mgmtObject->inc_byteTotalEnqueues (msg->contentSize ());
- if (msg->isPersistent ()) {
- mgmtObject->inc_msgPersistEnqueues ();
- mgmtObject->inc_bytePersistEnqueues (msg->contentSize ());
- }
- }
- }
- inline void mgntDeqStats(const boost::intrusive_ptr<Message>& msg)
- {
- if (mgmtObject != 0){
- mgmtObject->inc_msgTotalDequeues ();
- mgmtObject->inc_byteTotalDequeues (msg->contentSize());
- if (msg->isPersistent ()){
- mgmtObject->inc_msgPersistDequeues ();
- mgmtObject->inc_bytePersistDequeues (msg->contentSize());
- }
- }
- }
-
- void checkNotDeleted();
- void notifyDeleted();
-
- public:
-
- typedef boost::shared_ptr<Queue> shared_ptr;
-
- typedef std::vector<shared_ptr> vector;
-
- QPID_BROKER_EXTERN Queue(const std::string& name,
- bool autodelete = false,
- MessageStore* const store = 0,
- const OwnershipToken* const owner = 0,
- management::Manageable* parent = 0,
- Broker* broker = 0);
- QPID_BROKER_EXTERN ~Queue();
-
- QPID_BROKER_EXTERN bool dispatch(Consumer::shared_ptr);
-
- /**
- * Used to configure a new queue and create a persistent record
- * for it in store if required.
- */
- QPID_BROKER_EXTERN void create(const qpid::framing::FieldTable& settings);
-
- /**
- * Used to reconfigure a recovered queue (does not create
- * persistent record in store).
- */
- QPID_BROKER_EXTERN void configure(const qpid::framing::FieldTable& settings);
- void destroyed();
- QPID_BROKER_EXTERN void bound(const std::string& exchange,
- const std::string& key,
- const qpid::framing::FieldTable& args);
- //TODO: get unbind out of the public interface; only there for purposes of one unit test
- QPID_BROKER_EXTERN void unbind(ExchangeRegistry& exchanges);
- /**
- * Bind self to specified exchange, and record that binding for unbinding on delete.
- */
- bool bind(boost::shared_ptr<Exchange> exchange, const std::string& key,
- const qpid::framing::FieldTable& arguments=qpid::framing::FieldTable());
-
- QPID_BROKER_EXTERN bool acquire(const QueuedMessage& msg);
- QPID_BROKER_EXTERN bool acquireMessageAt(const qpid::framing::SequenceNumber& position, QueuedMessage& message);
-
- /**
- * Delivers a message to the queue. Will record it as
- * enqueued if persistent then process it.
- */
- QPID_BROKER_EXTERN void deliver(boost::intrusive_ptr<Message> msg);
- /**
- * Dispatches the messages immediately to a consumer if
- * one is available or stores it for later if not.
- */
- QPID_BROKER_EXTERN void process(boost::intrusive_ptr<Message>& msg);
- /**
- * Returns a message to the in-memory queue (due to lack
- * of acknowledegement from a receiver). If a consumer is
- * available it will be dispatched immediately, else it
- * will be returned to the front of the queue.
- */
- QPID_BROKER_EXTERN void requeue(const QueuedMessage& msg);
- /**
- * Used during recovery to add stored messages back to the queue
- */
- QPID_BROKER_EXTERN void recover(boost::intrusive_ptr<Message>& msg);
-
- QPID_BROKER_EXTERN void consume(Consumer::shared_ptr c,
- bool exclusive = false);
- QPID_BROKER_EXTERN void cancel(Consumer::shared_ptr c);
-
- uint32_t purge(const uint32_t purge_request=0, boost::shared_ptr<Exchange> dest=boost::shared_ptr<Exchange>()); //defaults to all messages
- QPID_BROKER_EXTERN void purgeExpired();
-
- //move qty # of messages to destination Queue destq
- uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
-
- QPID_BROKER_EXTERN uint32_t getMessageCount() const;
- QPID_BROKER_EXTERN uint32_t getEnqueueCompleteMessageCount() const;
- QPID_BROKER_EXTERN uint32_t getConsumerCount() const;
- inline const std::string& getName() const { return name; }
- bool isExclusiveOwner(const OwnershipToken* const o) const;
- void releaseExclusiveOwnership();
- bool setExclusiveOwner(const OwnershipToken* const o);
- bool hasExclusiveConsumer() const;
- bool hasExclusiveOwner() const;
- inline bool isDurable() const { return store != 0; }
- inline const framing::FieldTable& getSettings() const { return settings; }
- inline bool isAutoDelete() const { return autodelete; }
- bool canAutoDelete() const;
- const QueueBindings& getBindings() const { return bindings; }
-
- /**
- * used to take messages from in memory and flush down to disk.
- */
- QPID_BROKER_EXTERN void setLastNodeFailure();
- QPID_BROKER_EXTERN void clearLastNodeFailure();
-
- bool enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg, bool suppressPolicyCheck = false);
- void enqueueAborted(boost::intrusive_ptr<Message> msg);
- /**
- * dequeue from store (only done once messages is acknowledged)
- */
- QPID_BROKER_EXTERN bool dequeue(TransactionContext* ctxt, const QueuedMessage &msg);
- /**
- * Inform the queue that a previous transactional dequeue
- * committed.
- */
- void dequeueCommitted(const QueuedMessage& msg);
-
- /**
- * Inform queue of messages that were enqueued, have since
- * been acquired but not yet accepted or released (and
- * thus are still logically on the queue) - used in
- * clustered broker.
- */
- void updateEnqueued(const QueuedMessage& msg);
-
- /**
- * Test whether the specified message (identified by its
- * sequence/position), is still enqueued (note this
- * doesn't mean it is available for delivery as it may
- * have been delievered to a subscriber who has not yet
- * accepted it).
- */
- bool isEnqueued(const QueuedMessage& msg);
-
- /**
- * Gets the next available message
- */
- QPID_BROKER_EXTERN QueuedMessage get();
-
- /** Get the message at position pos */
- QPID_BROKER_EXTERN QueuedMessage find(framing::SequenceNumber pos) const;
-
- const QueuePolicy* getPolicy();
-
- void setAlternateExchange(boost::shared_ptr<Exchange> exchange);
- boost::shared_ptr<Exchange> getAlternateExchange();
- bool isLocal(boost::intrusive_ptr<Message>& msg);
-
- //PersistableQueue support:
- uint64_t getPersistenceId() const;
- void setPersistenceId(uint64_t persistenceId) const;
- void encode(framing::Buffer& buffer) const;
- uint32_t encodedSize() const;
-
- /**
- * Restores a queue from encoded data (used in recovery)
- *
- * Note: restored queue will be neither auto-deleted or have an
- * exclusive owner
- */
- static Queue::shared_ptr restore(QueueRegistry& queues, framing::Buffer& buffer);
- static void tryAutoDelete(Broker& broker, Queue::shared_ptr);
-
- virtual void setExternalQueueStore(ExternalQueueStore* inst);
-
- // Manageable entry points
- management::ManagementObject* GetManagementObject (void) const;
- management::Manageable::status_t
- ManagementMethod (uint32_t methodId, management::Args& args, std::string& text);
-
- /** Apply f to each Message on the queue. */
- template <class F> void eachMessage(F f) {
- sys::Mutex::ScopedLock l(messageLock);
- messages->foreach(f);
- }
-
- /** Apply f to each QueueBinding on the queue */
- template <class F> void eachBinding(F f) {
- bindings.eachBinding(f);
- }
-
- /** Apply f to each Observer on the queue */
- template <class F> void eachObserver(F f) {
- std::for_each<Observers::iterator, F>(observers.begin(), observers.end(), f);
- }
-
- /** Set the position sequence number for the next message on the queue.
- * Must be >= the current sequence number.
- * Used by cluster to replicate queues.
- */
- QPID_BROKER_EXTERN void setPosition(framing::SequenceNumber pos);
- /** return current position sequence number for the next message on the queue.
- */
- QPID_BROKER_EXTERN framing::SequenceNumber getPosition();
- void addObserver(boost::shared_ptr<QueueObserver>);
- QPID_BROKER_EXTERN void insertSequenceNumbers(const std::string& key);
- /**
- * Notify queue that recovery has completed.
- */
- void recoveryComplete(ExchangeRegistry& exchanges);
-
- // For cluster update
- QueueListeners& getListeners();
- Messages& getMessages();
- const Messages& getMessages() const;
-
- /**
- * Reserve space in policy for an enqueued message that
- * has been recovered in the prepared state (dtx only)
- */
- void recoverPrepared(boost::intrusive_ptr<Message>& msg);
-
- void flush();
-
- const Broker* getBroker();
-};
-}
-}
-
-
-#endif /*!_broker_Queue_h*/
diff --git a/cpp/src/qpid/broker/QueueBindings.cpp b/cpp/src/qpid/broker/QueueBindings.cpp
deleted file mode 100644
index 60d315acfe..0000000000
--- a/cpp/src/qpid/broker/QueueBindings.cpp
+++ /dev/null
@@ -1,47 +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.
- *
- */
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueueBindings.h"
-#include "qpid/broker/ExchangeRegistry.h"
-#include "qpid/framing/reply_exceptions.h"
-
-using qpid::framing::FieldTable;
-using qpid::framing::NotFoundException;
-using std::string;
-using namespace qpid::broker;
-
-void QueueBindings::add(const string& exchange, const string& key, const FieldTable& args)
-{
- bindings.push_back(QueueBinding(exchange, key, args));
-}
-
-void QueueBindings::unbind(ExchangeRegistry& exchanges, Queue::shared_ptr queue)
-{
- for (Bindings::iterator i = bindings.begin(); i != bindings.end(); i++) {
- try {
- exchanges.get(i->exchange)->unbind(queue, i->key, &(i->args));
- } catch (const NotFoundException&) {}
- }
-}
-
-QueueBinding::QueueBinding(const string& _exchange, const string& _key, const FieldTable& _args)
- : exchange(_exchange), key(_key), args(_args)
-{}
diff --git a/cpp/src/qpid/broker/QueueBindings.h b/cpp/src/qpid/broker/QueueBindings.h
deleted file mode 100644
index 1b90ba5540..0000000000
--- a/cpp/src/qpid/broker/QueueBindings.h
+++ /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.
- *
- */
-#ifndef _QueueBindings_
-#define _QueueBindings_
-
-#include "qpid/framing/FieldTable.h"
-#include <boost/ptr_container/ptr_list.hpp>
-#include <boost/shared_ptr.hpp>
-#include <algorithm>
-
-namespace qpid {
-namespace broker {
-
-class ExchangeRegistry;
-class Queue;
-
-struct QueueBinding{
- std::string exchange;
- std::string key;
- qpid::framing::FieldTable args;
- QueueBinding(const std::string& exchange, const std::string& key, const qpid::framing::FieldTable& args);
-};
-
-class QueueBindings
-{
- public:
-
- /** Apply f to each QueueBinding. */
- template <class F> void eachBinding(F f) const { std::for_each(bindings.begin(), bindings.end(), f); }
-
- void add(const std::string& exchange, const std::string& key, const qpid::framing::FieldTable& args);
- void unbind(ExchangeRegistry& exchanges, boost::shared_ptr<Queue> queue);
-
- private:
- typedef std::vector<QueueBinding> Bindings;
- Bindings bindings;
-};
-
-
-}} // namespace qpid::broker
-
-
-#endif
diff --git a/cpp/src/qpid/broker/QueueCleaner.cpp b/cpp/src/qpid/broker/QueueCleaner.cpp
deleted file mode 100644
index 3499ea8a4d..0000000000
--- a/cpp/src/qpid/broker/QueueCleaner.cpp
+++ /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.
- *
- */
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueueCleaner.h"
-
-#include "qpid/broker/Broker.h"
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace broker {
-
-QueueCleaner::QueueCleaner(QueueRegistry& q, sys::Timer& t) : queues(q), timer(t) {}
-
-QueueCleaner::~QueueCleaner()
-{
- if (task) task->cancel();
-}
-
-void QueueCleaner::start(qpid::sys::Duration p)
-{
- task = new Task(*this, p);
- timer.add(task);
-}
-
-QueueCleaner::Task::Task(QueueCleaner& p, qpid::sys::Duration d) : sys::TimerTask(d,"QueueCleaner"), parent(p) {}
-
-void QueueCleaner::Task::fire()
-{
- parent.fired();
-}
-
-namespace {
-struct CollectQueues
-{
- std::vector<Queue::shared_ptr>* queues;
- CollectQueues(std::vector<Queue::shared_ptr>* q) : queues(q) {}
- void operator()(Queue::shared_ptr q)
- {
- queues->push_back(q);
- }
-};
-}
-
-void QueueCleaner::fired()
-{
- //collect copy of list of queues to avoid holding registry lock while we perform purge
- std::vector<Queue::shared_ptr> copy;
- CollectQueues collect(&copy);
- queues.eachQueue(collect);
- std::for_each(copy.begin(), copy.end(), boost::bind(&Queue::purgeExpired, _1));
- task->setupNextFire();
- timer.add(task);
-}
-
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/QueueCleaner.h b/cpp/src/qpid/broker/QueueCleaner.h
deleted file mode 100644
index 11c2d180ac..0000000000
--- a/cpp/src/qpid/broker/QueueCleaner.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef QPID_BROKER_QUEUECLEANER_H
-#define QPID_BROKER_QUEUECLEANER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/sys/Timer.h"
-
-namespace qpid {
-namespace broker {
-
-class QueueRegistry;
-/**
- * TimerTask to purge expired messages from queues
- */
-class QueueCleaner
-{
- public:
- QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, sys::Timer& timer);
- QPID_BROKER_EXTERN ~QueueCleaner();
- QPID_BROKER_EXTERN void start(qpid::sys::Duration period);
- private:
- class Task : public sys::TimerTask
- {
- public:
- Task(QueueCleaner& parent, qpid::sys::Duration duration);
- void fire();
- private:
- QueueCleaner& parent;
- };
-
- boost::intrusive_ptr<sys::TimerTask> task;
- QueueRegistry& queues;
- sys::Timer& timer;
-
- void fired();
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_QUEUECLEANER_H*/
diff --git a/cpp/src/qpid/broker/QueueEvents.cpp b/cpp/src/qpid/broker/QueueEvents.cpp
deleted file mode 100644
index 2c540ff1ad..0000000000
--- a/cpp/src/qpid/broker/QueueEvents.cpp
+++ /dev/null
@@ -1,147 +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.
- *
- */
-#include "qpid/broker/QueueEvents.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueueObserver.h"
-#include "qpid/Exception.h"
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace broker {
-
-QueueEvents::QueueEvents(const boost::shared_ptr<sys::Poller>& poller, bool isSync) :
- eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller), enabled(true), sync(isSync)
-{
- if (!sync) eventQueue.start();
-}
-
-QueueEvents::~QueueEvents()
-{
- if (!sync) eventQueue.stop();
-}
-
-void QueueEvents::enqueued(const QueuedMessage& m)
-{
- if (enabled) {
- Event enq(ENQUEUE, m);
- if (sync) {
- for (Listeners::iterator j = listeners.begin(); j != listeners.end(); j++)
- j->second(enq);
- } else {
- eventQueue.push(enq);
- }
- }
-}
-
-void QueueEvents::dequeued(const QueuedMessage& m)
-{
- if (enabled) {
- Event deq(DEQUEUE, m);
- if (sync) {
- for (Listeners::iterator j = listeners.begin(); j != listeners.end(); j++)
- j->second(deq);
- } else {
- eventQueue.push(Event(DEQUEUE, m));
- }
- }
-}
-
-void QueueEvents::registerListener(const std::string& id, const EventListener& listener)
-{
- qpid::sys::Mutex::ScopedLock l(lock);
- if (listeners.find(id) == listeners.end()) {
- listeners[id] = listener;
- } else {
- throw Exception(QPID_MSG("Event listener already registered for '" << id << "'"));
- }
-}
-
-void QueueEvents::unregisterListener(const std::string& id)
-{
- qpid::sys::Mutex::ScopedLock l(lock);
- if (listeners.find(id) == listeners.end()) {
- throw Exception(QPID_MSG("No event listener registered for '" << id << "'"));
- } else {
- listeners.erase(id);
- }
-}
-
-QueueEvents::EventQueue::Batch::const_iterator
-QueueEvents::handle(const EventQueue::Batch& events) {
- qpid::sys::Mutex::ScopedLock l(lock);
- for (EventQueue::Batch::const_iterator i = events.begin(); i != events.end(); ++i) {
- for (Listeners::iterator j = listeners.begin(); j != listeners.end(); j++) {
- j->second(*i);
- }
- }
- return events.end();
-}
-
-void QueueEvents::shutdown()
-{
- if (!sync && !eventQueue.empty() && !listeners.empty()) eventQueue.shutdown();
-}
-
-void QueueEvents::enable()
-{
- enabled = true;
- QPID_LOG(debug, "Queue events enabled");
-}
-
-void QueueEvents::disable()
-{
- enabled = false;
- QPID_LOG(debug, "Queue events disabled");
-}
-
-bool QueueEvents::isSync()
-{
- return sync;
-}
-
-class EventGenerator : public QueueObserver
-{
- public:
- EventGenerator(QueueEvents& mgr, bool enqOnly) : manager(mgr), enqueueOnly(enqOnly) {}
- void enqueued(const QueuedMessage& m)
- {
- manager.enqueued(m);
- }
- void dequeued(const QueuedMessage& m)
- {
- if (!enqueueOnly) manager.dequeued(m);
- }
- private:
- QueueEvents& manager;
- const bool enqueueOnly;
-};
-
-void QueueEvents::observe(Queue& queue, bool enqueueOnly)
-{
- boost::shared_ptr<QueueObserver> observer(new EventGenerator(*this, enqueueOnly));
- queue.addObserver(observer);
-}
-
-
-QueueEvents::Event::Event(EventType t, const QueuedMessage& m) : type(t), msg(m) {}
-
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/QueueEvents.h b/cpp/src/qpid/broker/QueueEvents.h
deleted file mode 100644
index fcddfe9092..0000000000
--- a/cpp/src/qpid/broker/QueueEvents.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef QPID_BROKER_QUEUEEVENTS_H
-#define QPID_BROKER_QUEUEEVENTS_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/PollableQueue.h"
-#include <map>
-#include <string>
-#include <boost/function.hpp>
-
-namespace qpid {
-namespace broker {
-
-/**
- * Event manager for queue events. Allows queues to indicate when
- * events have occured; allows listeners to register for notification
- * of this. The notification happens asynchronously, in a separate
- * thread.
- */
-class QueueEvents
-{
- public:
- enum EventType {ENQUEUE, DEQUEUE};
-
- struct Event
- {
- EventType type;
- QueuedMessage msg;
-
- QPID_BROKER_EXTERN Event(EventType, const QueuedMessage&);
- };
-
- typedef boost::function<void (Event)> EventListener;
-
- QPID_BROKER_EXTERN QueueEvents(const boost::shared_ptr<sys::Poller>& poller, bool isSync = false);
- QPID_BROKER_EXTERN ~QueueEvents();
- QPID_BROKER_EXTERN void enqueued(const QueuedMessage&);
- QPID_BROKER_EXTERN void dequeued(const QueuedMessage&);
- QPID_BROKER_EXTERN void registerListener(const std::string& id,
- const EventListener&);
- QPID_BROKER_EXTERN void unregisterListener(const std::string& id);
- void enable();
- void disable();
- void observe(Queue&, bool enqueueOnly);
- //process all outstanding events
- QPID_BROKER_EXTERN void shutdown();
- QPID_BROKER_EXTERN bool isSync();
- private:
- typedef qpid::sys::PollableQueue<Event> EventQueue;
- typedef std::map<std::string, EventListener> Listeners;
-
- EventQueue eventQueue;
- Listeners listeners;
- volatile bool enabled;
- qpid::sys::Mutex lock;//protect listeners from concurrent access
- bool sync;
-
- EventQueue::Batch::const_iterator handle(const EventQueue::Batch& e);
-
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_QUEUEEVENTS_H*/
diff --git a/cpp/src/qpid/broker/QueueFlowLimit.cpp b/cpp/src/qpid/broker/QueueFlowLimit.cpp
deleted file mode 100644
index b2e2e54bdf..0000000000
--- a/cpp/src/qpid/broker/QueueFlowLimit.cpp
+++ /dev/null
@@ -1,407 +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.
- *
- */
-#include "qpid/broker/QueueFlowLimit.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/Exception.h"
-#include "qpid/framing/FieldValue.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/broker/SessionState.h"
-#include "qpid/sys/ClusterSafe.h"
-
-#include "qmf/org/apache/qpid/broker/Queue.h"
-
-#include <sstream>
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-
-namespace {
- /** ensure that the configured flow control stop and resume values are
- * valid with respect to the maximum queue capacity, and each other
- */
- template <typename T>
- void validateFlowConfig(T max, T& stop, T& resume, const std::string& type, const std::string& queue)
- {
- if (resume > stop) {
- throw InvalidArgumentException(QPID_MSG("Queue \"" << queue << "\": qpid.flow_resume_" << type
- << "=" << resume
- << " must be less than qpid.flow_stop_" << type
- << "=" << stop));
- }
- if (resume == 0) resume = stop;
- if (max != 0 && (max < stop)) {
- throw InvalidArgumentException(QPID_MSG("Queue \"" << queue << "\": qpid.flow_stop_" << type
- << "=" << stop
- << " must be less than qpid.max_" << type
- << "=" << max));
- }
- }
-
- /** extract a capacity value as passed in an argument map
- */
- uint64_t getCapacity(const FieldTable& settings, const std::string& key, uint64_t defaultValue)
- {
- FieldTable::ValuePtr v = settings.get(key);
-
- int64_t result = 0;
-
- if (!v) return defaultValue;
- if (v->getType() == 0x23) {
- QPID_LOG(debug, "Value for " << key << " specified as float: " << v->get<float>());
- } else if (v->getType() == 0x33) {
- QPID_LOG(debug, "Value for " << key << " specified as double: " << v->get<double>());
- } else if (v->convertsTo<int64_t>()) {
- result = v->get<int64_t>();
- QPID_LOG(debug, "Got integer value for " << key << ": " << result);
- if (result >= 0) return result;
- } else if (v->convertsTo<string>()) {
- string s(v->get<string>());
- QPID_LOG(debug, "Got string value for " << key << ": " << s);
- std::istringstream convert(s);
- if (convert >> result && result >= 0) return result;
- }
-
- QPID_LOG(warning, "Cannot convert " << key << " to unsigned integer, using default (" << defaultValue << ")");
- return defaultValue;
- }
-}
-
-
-
-QueueFlowLimit::QueueFlowLimit(Queue *_queue,
- uint32_t _flowStopCount, uint32_t _flowResumeCount,
- uint64_t _flowStopSize, uint64_t _flowResumeSize)
- : StatefulQueueObserver(std::string("QueueFlowLimit")), queue(_queue), queueName("<unknown>"),
- flowStopCount(_flowStopCount), flowResumeCount(_flowResumeCount),
- flowStopSize(_flowStopSize), flowResumeSize(_flowResumeSize),
- flowStopped(false), count(0), size(0), queueMgmtObj(0), broker(0)
-{
- uint32_t maxCount(0);
- uint64_t maxSize(0);
-
- if (queue) {
- queueName = _queue->getName();
- if (queue->getPolicy()) {
- maxSize = _queue->getPolicy()->getMaxSize();
- maxCount = _queue->getPolicy()->getMaxCount();
- }
- broker = queue->getBroker();
- queueMgmtObj = dynamic_cast<_qmfBroker::Queue*> (queue->GetManagementObject());
- if (queueMgmtObj) {
- queueMgmtObj->set_flowStopped(isFlowControlActive());
- }
- }
- validateFlowConfig( maxCount, flowStopCount, flowResumeCount, "count", queueName );
- validateFlowConfig( maxSize, flowStopSize, flowResumeSize, "size", queueName );
- QPID_LOG(info, "Queue \"" << queueName << "\": Flow limit created: flowStopCount=" << flowStopCount
- << ", flowResumeCount=" << flowResumeCount
- << ", flowStopSize=" << flowStopSize << ", flowResumeSize=" << flowResumeSize );
-}
-
-
-QueueFlowLimit::~QueueFlowLimit()
-{
- sys::Mutex::ScopedLock l(indexLock);
- if (!index.empty()) {
- // we're gone - release all pending msgs
- for (std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::iterator itr = index.begin();
- itr != index.end(); ++itr)
- if (itr->second)
- try {
- itr->second->getIngressCompletion().finishCompleter();
- } catch (...) {} // ignore - not safe for a destructor to throw.
- index.clear();
- }
-}
-
-
-void QueueFlowLimit::enqueued(const QueuedMessage& msg)
-{
- sys::Mutex::ScopedLock l(indexLock);
-
- ++count;
- size += msg.payload->contentSize();
-
- if (!flowStopped) {
- if (flowStopCount && count > flowStopCount) {
- flowStopped = true;
- QPID_LOG(info, "Queue \"" << queueName << "\": has reached " << flowStopCount << " enqueued messages. Producer flow control activated." );
- } else if (flowStopSize && size > flowStopSize) {
- flowStopped = true;
- QPID_LOG(info, "Queue \"" << queueName << "\": has reached " << flowStopSize << " enqueued bytes. Producer flow control activated." );
- }
- if (flowStopped && queueMgmtObj) {
- queueMgmtObj->set_flowStopped(true);
- queueMgmtObj->inc_flowStoppedCount();
- }
- }
-
- if (flowStopped || !index.empty()) {
- // ignore flow control if we are populating the queue due to cluster replication:
- if (broker && broker->isClusterUpdatee()) {
- QPID_LOG(trace, "Queue \"" << queueName << "\": ignoring flow control for msg pos=" << msg.position);
- return;
- }
- QPID_LOG(trace, "Queue \"" << queueName << "\": setting flow control for msg pos=" << msg.position);
- msg.payload->getIngressCompletion().startCompleter(); // don't complete until flow resumes
- bool unique;
- unique = index.insert(std::pair<framing::SequenceNumber, boost::intrusive_ptr<Message> >(msg.position, msg.payload)).second;
- assert(unique);
- }
-}
-
-
-
-void QueueFlowLimit::dequeued(const QueuedMessage& msg)
-{
- sys::Mutex::ScopedLock l(indexLock);
-
- if (count > 0) {
- --count;
- } else {
- throw Exception(QPID_MSG("Flow limit count underflow on dequeue. Queue=" << queueName));
- }
-
- uint64_t _size = msg.payload->contentSize();
- if (_size <= size) {
- size -= _size;
- } else {
- throw Exception(QPID_MSG("Flow limit size underflow on dequeue. Queue=" << queueName));
- }
-
- if (flowStopped &&
- (flowResumeSize == 0 || size < flowResumeSize) &&
- (flowResumeCount == 0 || count < flowResumeCount)) {
- flowStopped = false;
- if (queueMgmtObj)
- queueMgmtObj->set_flowStopped(false);
- QPID_LOG(info, "Queue \"" << queueName << "\": has drained below the flow control resume level. Producer flow control deactivated." );
- }
-
- if (!index.empty()) {
- if (!flowStopped) {
- // flow enabled - release all pending msgs
- for (std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::iterator itr = index.begin();
- itr != index.end(); ++itr)
- if (itr->second)
- itr->second->getIngressCompletion().finishCompleter();
- index.clear();
- } else {
- // even if flow controlled, we must release this msg as it is being dequeued
- std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::iterator itr = index.find(msg.position);
- if (itr != index.end()) { // this msg is flow controlled, release it:
- msg.payload->getIngressCompletion().finishCompleter();
- index.erase(itr);
- }
- }
- }
-}
-
-
-void QueueFlowLimit::encode(Buffer& buffer) const
-{
- buffer.putLong(flowStopCount);
- buffer.putLong(flowResumeCount);
- buffer.putLongLong(flowStopSize);
- buffer.putLongLong(flowResumeSize);
- buffer.putLong(count);
- buffer.putLongLong(size);
-}
-
-
-void QueueFlowLimit::decode ( Buffer& buffer )
-{
- flowStopCount = buffer.getLong();
- flowResumeCount = buffer.getLong();
- flowStopSize = buffer.getLongLong();
- flowResumeSize = buffer.getLongLong();
- count = buffer.getLong();
- size = buffer.getLongLong();
-}
-
-
-uint32_t QueueFlowLimit::encodedSize() const {
- return sizeof(uint32_t) + // flowStopCount
- sizeof(uint32_t) + // flowResumecount
- sizeof(uint64_t) + // flowStopSize
- sizeof(uint64_t) + // flowResumeSize
- sizeof(uint32_t) + // count
- sizeof(uint64_t); // size
-}
-
-
-const std::string QueueFlowLimit::flowStopCountKey("qpid.flow_stop_count");
-const std::string QueueFlowLimit::flowResumeCountKey("qpid.flow_resume_count");
-const std::string QueueFlowLimit::flowStopSizeKey("qpid.flow_stop_size");
-const std::string QueueFlowLimit::flowResumeSizeKey("qpid.flow_resume_size");
-uint64_t QueueFlowLimit::defaultMaxSize;
-uint QueueFlowLimit::defaultFlowStopRatio;
-uint QueueFlowLimit::defaultFlowResumeRatio;
-
-
-void QueueFlowLimit::setDefaults(uint64_t maxQueueSize, uint flowStopRatio, uint flowResumeRatio)
-{
- defaultMaxSize = maxQueueSize;
- defaultFlowStopRatio = flowStopRatio;
- defaultFlowResumeRatio = flowResumeRatio;
-
- /** @todo KAG: Verify valid range on Broker::Options instead of here */
- if (flowStopRatio > 100 || flowResumeRatio > 100)
- throw InvalidArgumentException(QPID_MSG("Default queue flow ratios must be between 0 and 100, inclusive:"
- << " flowStopRatio=" << flowStopRatio
- << " flowResumeRatio=" << flowResumeRatio));
- if (flowResumeRatio > flowStopRatio)
- throw InvalidArgumentException(QPID_MSG("Default queue flow stop ratio must be >= flow resume ratio:"
- << " flowStopRatio=" << flowStopRatio
- << " flowResumeRatio=" << flowResumeRatio));
-}
-
-
-void QueueFlowLimit::observe(Queue& queue, const qpid::framing::FieldTable& settings)
-{
- QueueFlowLimit *ptr = createLimit( &queue, settings );
- if (ptr) {
- boost::shared_ptr<QueueFlowLimit> observer(ptr);
- queue.addObserver(observer);
- }
-}
-
-/** returns ptr to a QueueFlowLimit, else 0 if no limit */
-QueueFlowLimit *QueueFlowLimit::createLimit(Queue *queue, const qpid::framing::FieldTable& settings)
-{
- std::string type(QueuePolicy::getType(settings));
-
- if (type == QueuePolicy::RING || type == QueuePolicy::RING_STRICT) {
- // The size of a RING queue is limited by design - no need for flow control.
- return 0;
- }
-
- if (settings.get(flowStopCountKey) || settings.get(flowStopSizeKey) ||
- settings.get(flowResumeCountKey) || settings.get(flowResumeSizeKey)) {
- // user provided (some) flow settings manually...
- uint32_t flowStopCount = getCapacity(settings, flowStopCountKey, 0);
- uint32_t flowResumeCount = getCapacity(settings, flowResumeCountKey, 0);
- uint64_t flowStopSize = getCapacity(settings, flowStopSizeKey, 0);
- uint64_t flowResumeSize = getCapacity(settings, flowResumeSizeKey, 0);
- if (flowStopCount == 0 && flowStopSize == 0) { // disable flow control
- return 0;
- }
- return new QueueFlowLimit(queue, flowStopCount, flowResumeCount, flowStopSize, flowResumeSize);
- }
-
- if (defaultFlowStopRatio) { // broker has a default ratio setup...
- uint64_t maxByteCount = getCapacity(settings, QueuePolicy::maxSizeKey, defaultMaxSize);
- uint64_t flowStopSize = (uint64_t)(maxByteCount * (defaultFlowStopRatio/100.0) + 0.5);
- uint64_t flowResumeSize = (uint64_t)(maxByteCount * (defaultFlowResumeRatio/100.0));
- uint32_t maxMsgCount = getCapacity(settings, QueuePolicy::maxCountKey, 0); // no size by default
- uint32_t flowStopCount = (uint32_t)(maxMsgCount * (defaultFlowStopRatio/100.0) + 0.5);
- uint32_t flowResumeCount = (uint32_t)(maxMsgCount * (defaultFlowResumeRatio/100.0));
-
- return new QueueFlowLimit(queue, flowStopCount, flowResumeCount, flowStopSize, flowResumeSize);
- }
- return 0;
-}
-
-/* Cluster replication */
-
-namespace {
- /** pack a set of sequence number ranges into a framing::Array */
- void buildSeqRangeArray(qpid::framing::Array *seqs,
- const qpid::framing::SequenceNumber& first,
- const qpid::framing::SequenceNumber& last)
- {
- seqs->push_back(qpid::framing::Array::ValuePtr(new Unsigned32Value(first)));
- seqs->push_back(qpid::framing::Array::ValuePtr(new Unsigned32Value(last)));
- }
-}
-
-/** Runs on UPDATER to snapshot current state */
-void QueueFlowLimit::getState(qpid::framing::FieldTable& state ) const
-{
- sys::Mutex::ScopedLock l(indexLock);
- state.clear();
-
- framing::SequenceSet ss;
- if (!index.empty()) {
- /* replicate the set of messages pending flow control */
- for (std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::const_iterator itr = index.begin();
- itr != index.end(); ++itr) {
- ss.add(itr->first);
- }
- framing::Array seqs(TYPE_CODE_UINT32);
- typedef boost::function<void(framing::SequenceNumber, framing::SequenceNumber)> arrayBuilder;
- ss.for_each((arrayBuilder)boost::bind(&buildSeqRangeArray, &seqs, _1, _2));
- state.setArray("pendingMsgSeqs", seqs);
- }
- QPID_LOG(debug, "Queue \"" << queueName << "\": flow limit replicating pending msgs, range=" << ss);
-}
-
-
-/** called on UPDATEE to set state from snapshot */
-void QueueFlowLimit::setState(const qpid::framing::FieldTable& state)
-{
- sys::Mutex::ScopedLock l(indexLock);
- index.clear();
-
- framing::SequenceSet fcmsg;
- framing::Array seqArray(TYPE_CODE_UINT32);
- if (state.getArray("pendingMsgSeqs", seqArray)) {
- assert((seqArray.count() & 0x01) == 0); // must be even since they are sequence ranges
- framing::Array::const_iterator i = seqArray.begin();
- while (i != seqArray.end()) {
- framing::SequenceNumber first((*i)->getIntegerValue<uint32_t, 4>());
- ++i;
- framing::SequenceNumber last((*i)->getIntegerValue<uint32_t, 4>());
- ++i;
- fcmsg.add(first, last);
- for (SequenceNumber seq = first; seq <= last; ++seq) {
- QueuedMessage msg(queue->find(seq)); // fyi: msg.payload may be null if msg is delivered & unacked
- bool unique;
- unique = index.insert(std::pair<framing::SequenceNumber, boost::intrusive_ptr<Message> >(seq, msg.payload)).second;
- assert(unique);
- }
- }
- }
-
- flowStopped = index.size() != 0;
- if (queueMgmtObj) {
- queueMgmtObj->set_flowStopped(isFlowControlActive());
- }
- QPID_LOG(debug, "Queue \"" << queueName << "\": flow limit replicated the pending msgs, range=" << fcmsg)
-}
-
-
-namespace qpid {
- namespace broker {
-
-std::ostream& operator<<(std::ostream& out, const QueueFlowLimit& f)
-{
- out << "; flowStopCount=" << f.flowStopCount << ", flowResumeCount=" << f.flowResumeCount;
- out << "; flowStopSize=" << f.flowStopSize << ", flowResumeSize=" << f.flowResumeSize;
- return out;
-}
-
- }
-}
-
diff --git a/cpp/src/qpid/broker/QueueFlowLimit.h b/cpp/src/qpid/broker/QueueFlowLimit.h
deleted file mode 100644
index c02e479976..0000000000
--- a/cpp/src/qpid/broker/QueueFlowLimit.h
+++ /dev/null
@@ -1,129 +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.
- *
- */
-#ifndef _QueueFlowLimit_
-#define _QueueFlowLimit_
-
-#include <list>
-#include <set>
-#include <iostream>
-#include <memory>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/broker/StatefulQueueObserver.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/AtomicValue.h"
-#include "qpid/sys/Mutex.h"
-
-namespace qmf {
-namespace org {
-namespace apache {
-namespace qpid {
-namespace broker {
- class Queue;
-}}}}}
-namespace _qmfBroker = qmf::org::apache::qpid::broker;
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-
-/**
- * Producer flow control: when level is > flowStop*, flow control is ON.
- * then level is < flowResume*, flow control is OFF. If == 0, flow control
- * is not used. If both byte and msg count thresholds are set, then
- * passing _either_ level may turn flow control ON, but _both_ must be
- * below level before flow control will be turned OFF.
- */
- class QueueFlowLimit : public StatefulQueueObserver
-{
- static uint64_t defaultMaxSize;
- static uint defaultFlowStopRatio;
- static uint defaultFlowResumeRatio;
-
- Queue *queue;
- std::string queueName;
-
- uint32_t flowStopCount;
- uint32_t flowResumeCount;
- uint64_t flowStopSize;
- uint64_t flowResumeSize;
- bool flowStopped; // true = producers held in flow control
-
- // current queue utilization
- uint32_t count;
- uint64_t size;
-
- public:
- static QPID_BROKER_EXTERN const std::string flowStopCountKey;
- static QPID_BROKER_EXTERN const std::string flowResumeCountKey;
- static QPID_BROKER_EXTERN const std::string flowStopSizeKey;
- static QPID_BROKER_EXTERN const std::string flowResumeSizeKey;
-
- QPID_BROKER_EXTERN virtual ~QueueFlowLimit();
-
- /** the queue has added QueuedMessage. Returns true if flow state changes */
- QPID_BROKER_EXTERN void enqueued(const QueuedMessage&);
- /** the queue has removed QueuedMessage. Returns true if flow state changes */
- QPID_BROKER_EXTERN void dequeued(const QueuedMessage&);
-
- /** for clustering: */
- QPID_BROKER_EXTERN void getState(qpid::framing::FieldTable&) const;
- QPID_BROKER_EXTERN void setState(const qpid::framing::FieldTable&);
-
- uint32_t getFlowStopCount() const { return flowStopCount; }
- uint32_t getFlowResumeCount() const { return flowResumeCount; }
- uint64_t getFlowStopSize() const { return flowStopSize; }
- uint64_t getFlowResumeSize() const { return flowResumeSize; }
-
- uint32_t getFlowCount() const { return count; }
- uint64_t getFlowSize() const { return size; }
- bool isFlowControlActive() const { return flowStopped; }
- bool monitorFlowControl() const { return flowStopCount || flowStopSize; }
-
- void encode(framing::Buffer& buffer) const;
- void decode(framing::Buffer& buffer);
- uint32_t encodedSize() const;
-
- static QPID_BROKER_EXTERN void observe(Queue& queue, const qpid::framing::FieldTable& settings);
- static QPID_BROKER_EXTERN void setDefaults(uint64_t defaultMaxSize, uint defaultFlowStopRatio, uint defaultFlowResumeRatio);
-
- friend QPID_BROKER_EXTERN std::ostream& operator<<(std::ostream&, const QueueFlowLimit&);
-
- protected:
- // msgs waiting for flow to become available.
- std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> > index;
- mutable qpid::sys::Mutex indexLock;
-
- _qmfBroker::Queue *queueMgmtObj;
-
- const Broker *broker;
-
- QPID_BROKER_EXTERN QueueFlowLimit(Queue *queue,
- uint32_t flowStopCount, uint32_t flowResumeCount,
- uint64_t flowStopSize, uint64_t flowResumeSize);
- static QPID_BROKER_EXTERN QueueFlowLimit *createLimit(Queue *queue, const qpid::framing::FieldTable& settings);
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/QueueListeners.cpp b/cpp/src/qpid/broker/QueueListeners.cpp
deleted file mode 100644
index 591f4443bb..0000000000
--- a/cpp/src/qpid/broker/QueueListeners.cpp
+++ /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.
- *
- */
-#include "qpid/broker/QueueListeners.h"
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace broker {
-
-void QueueListeners::addListener(Consumer::shared_ptr c)
-{
- if (!c->inListeners) {
- if (c->acquires) {
- add(consumers, c);
- } else {
- add(browsers, c);
- }
- c->inListeners = true;
- }
-}
-
-void QueueListeners::removeListener(Consumer::shared_ptr c)
-{
- if (c->inListeners) {
- if (c->acquires) {
- remove(consumers, c);
- } else {
- remove(browsers, c);
- }
- c->inListeners = false;
- }
-}
-
-void QueueListeners::populate(NotificationSet& set)
-{
- if (consumers.size()) {
- set.consumer = consumers.front();
- consumers.pop_front();
- set.consumer->inListeners = false;
- } else {
- // Don't swap the deques, hang on to the memory allocated.
- set.browsers = browsers;
- browsers.clear();
- for (Listeners::iterator i = set.browsers.begin(); i != set.browsers.end(); i++)
- (*i)->inListeners = false;
- }
-}
-
-void QueueListeners::add(Listeners& listeners, Consumer::shared_ptr c)
-{
- listeners.push_back(c);
-}
-
-void QueueListeners::remove(Listeners& listeners, Consumer::shared_ptr c)
-{
- Listeners::iterator i = std::find(listeners.begin(), listeners.end(), c);
- if (i != listeners.end()) listeners.erase(i);
-}
-
-void QueueListeners::NotificationSet::notify()
-{
- if (consumer) consumer->notify();
- else std::for_each(browsers.begin(), browsers.end(), boost::mem_fn(&Consumer::notify));
-}
-
-bool QueueListeners::contains(Consumer::shared_ptr c) const {
- return c->inListeners;
-}
-
-void QueueListeners::ListenerSet::notifyAll()
-{
- std::for_each(listeners.begin(), listeners.end(), boost::mem_fn(&Consumer::notify));
-}
-
-void QueueListeners::snapshot(ListenerSet& set)
-{
- set.listeners.insert(set.listeners.end(), consumers.begin(), consumers.end());
- set.listeners.insert(set.listeners.end(), browsers.begin(), browsers.end());
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/QueueListeners.h b/cpp/src/qpid/broker/QueueListeners.h
deleted file mode 100644
index 0659499253..0000000000
--- a/cpp/src/qpid/broker/QueueListeners.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef QPID_BROKER_QUEUELISTENERS_H
-#define QPID_BROKER_QUEUELISTENERS_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/Consumer.h"
-#include <deque>
-
-namespace qpid {
-namespace broker {
-
-/**
- * Track and notify components that wish to be notified of messages
- * that become available on a queue.
- *
- * None of the methods defined here are protected by locking. However
- * the populate method allows a 'snapshot' to be taken of the
- * listeners to be notified. NotificationSet::notify() may then be
- * called outside of any lock that protects the QueueListeners
- * instance from concurrent access.
- */
-class QueueListeners
-{
- public:
- typedef std::deque<Consumer::shared_ptr> Listeners;
-
- class NotificationSet
- {
- public:
- void notify();
- private:
- Listeners browsers;
- Consumer::shared_ptr consumer;
- friend class QueueListeners;
- };
-
- class ListenerSet
- {
- public:
- void notifyAll();
- private:
- Listeners listeners;
- friend class QueueListeners;
- };
-
- void addListener(Consumer::shared_ptr);
- void removeListener(Consumer::shared_ptr);
- void populate(NotificationSet&);
- void snapshot(ListenerSet&);
- bool contains(Consumer::shared_ptr c) const;
- void notifyAll();
-
- template <class F> void eachListener(F f) {
- std::for_each(browsers.begin(), browsers.end(), f);
- std::for_each(consumers.begin(), consumers.end(), f);
- }
-
- private:
- Listeners consumers;
- Listeners browsers;
-
- void add(Listeners&, Consumer::shared_ptr);
- void remove(Listeners&, Consumer::shared_ptr);
-
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_QUEUELISTENERS_H*/
diff --git a/cpp/src/qpid/broker/QueueObserver.h b/cpp/src/qpid/broker/QueueObserver.h
deleted file mode 100644
index 3ca01c051e..0000000000
--- a/cpp/src/qpid/broker/QueueObserver.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef QPID_BROKER_QUEUEOBSERVER_H
-#define QPID_BROKER_QUEUEOBSERVER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-namespace qpid {
-namespace broker {
-
-struct QueuedMessage;
-/**
- * Interface for notifying classes who want to act as 'observers' of a
- * queue of particular events.
- */
-class QueueObserver
-{
- public:
- virtual ~QueueObserver() {}
- virtual void enqueued(const QueuedMessage&) = 0;
- virtual void dequeued(const QueuedMessage&) = 0;
- private:
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_QUEUEOBSERVER_H*/
diff --git a/cpp/src/qpid/broker/QueuePolicy.cpp b/cpp/src/qpid/broker/QueuePolicy.cpp
deleted file mode 100644
index a93a6332fd..0000000000
--- a/cpp/src/qpid/broker/QueuePolicy.cpp
+++ /dev/null
@@ -1,360 +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.
- *
- */
-#include "qpid/broker/QueuePolicy.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/PriorityQueue.h"
-#include "qpid/Exception.h"
-#include "qpid/framing/FieldValue.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include <sstream>
-
-using namespace qpid::broker;
-using namespace qpid::framing;
-
-QueuePolicy::QueuePolicy(const std::string& _name, uint32_t _maxCount, uint64_t _maxSize, const std::string& _type) :
- maxCount(_maxCount), maxSize(_maxSize), type(_type), count(0), size(0), policyExceeded(false), name(_name) {
- QPID_LOG(info, "Queue \"" << name << "\": Policy created: type=" << type << "; maxCount=" << maxCount << "; maxSize=" << maxSize);
-}
-
-void QueuePolicy::enqueued(uint64_t _size)
-{
- if (maxCount) ++count;
- if (maxSize) size += _size;
-}
-
-void QueuePolicy::dequeued(uint64_t _size)
-{
- if (maxCount) {
- if (count > 0) {
- --count;
- } else {
- throw Exception(QPID_MSG("Attempted count underflow on dequeue(" << _size << "): " << *this));
- }
- }
- if (maxSize) {
- if (_size > size) {
- throw Exception(QPID_MSG("Attempted size underflow on dequeue(" << _size << "): " << *this));
- } else {
- size -= _size;
- }
- }
-}
-
-bool QueuePolicy::checkLimit(boost::intrusive_ptr<Message> m)
-{
- bool sizeExceeded = maxSize && (size + m->contentSize()) > maxSize;
- bool countExceeded = maxCount && (count + 1) > maxCount;
- bool exceeded = sizeExceeded || countExceeded;
- if (exceeded) {
- if (!policyExceeded) {
- policyExceeded = true;
- if (sizeExceeded) QPID_LOG(info, "Queue cumulative message size exceeded policy for " << name);
- if (countExceeded) QPID_LOG(info, "Queue message count exceeded policy for " << name);
- }
- } else {
- if (policyExceeded) {
- policyExceeded = false;
- QPID_LOG(info, "Queue cumulative message size and message count within policy for " << name);
- }
- }
- return !exceeded;
-}
-
-void QueuePolicy::tryEnqueue(boost::intrusive_ptr<Message> m)
-{
- if (checkLimit(m)) {
- enqueued(m->contentSize());
- } else {
- throw ResourceLimitExceededException(QPID_MSG("Policy exceeded on " << name << ", policy: " << *this));
- }
-}
-
-void QueuePolicy::recoverEnqueued(boost::intrusive_ptr<Message> m)
-{
- tryEnqueue(m);
-}
-
-void QueuePolicy::enqueueAborted(boost::intrusive_ptr<Message> m)
-{
- dequeued(m->contentSize());
-}
-
-void QueuePolicy::enqueued(const QueuedMessage&) {}
-
-void QueuePolicy::dequeued(const QueuedMessage& m)
-{
- dequeued(m.payload->contentSize());
-}
-
-bool QueuePolicy::isEnqueued(const QueuedMessage&)
-{
- return true;
-}
-
-void QueuePolicy::update(FieldTable& settings)
-{
- if (maxCount) settings.setInt(maxCountKey, maxCount);
- if (maxSize) settings.setInt(maxSizeKey, maxSize);
- settings.setString(typeKey, type);
-}
-
-uint32_t QueuePolicy::getCapacity(const FieldTable& settings, const std::string& key, uint32_t defaultValue)
-{
- FieldTable::ValuePtr v = settings.get(key);
-
- int32_t result = 0;
-
- if (!v) return defaultValue;
- if (v->getType() == 0x23) {
- QPID_LOG(debug, "Value for " << key << " specified as float: " << v->get<float>());
- } else if (v->getType() == 0x33) {
- QPID_LOG(debug, "Value for " << key << " specified as double: " << v->get<double>());
- } else if (v->convertsTo<int>()) {
- result = v->get<int>();
- QPID_LOG(debug, "Got integer value for " << key << ": " << result);
- if (result >= 0) return result;
- } else if (v->convertsTo<string>()) {
- string s(v->get<string>());
- QPID_LOG(debug, "Got string value for " << key << ": " << s);
- std::istringstream convert(s);
- if (convert >> result && result >= 0 && convert.eof()) return result;
- }
-
- throw IllegalArgumentException(QPID_MSG("Cannot convert " << key << " to unsigned integer: " << *v));
-}
-
-std::string QueuePolicy::getType(const FieldTable& settings)
-{
- FieldTable::ValuePtr v = settings.get(typeKey);
- if (v && v->convertsTo<std::string>()) {
- std::string t = v->get<std::string>();
- std::transform(t.begin(), t.end(), t.begin(), tolower);
- if (t == REJECT || t == FLOW_TO_DISK || t == RING || t == RING_STRICT) return t;
- }
- return REJECT;
-}
-
-void QueuePolicy::setDefaultMaxSize(uint64_t s)
-{
- defaultMaxSize = s;
-}
-
-void QueuePolicy::getPendingDequeues(Messages&) {}
-
-
-
-
-void QueuePolicy::encode(Buffer& buffer) const
-{
- buffer.putLong(maxCount);
- buffer.putLongLong(maxSize);
- buffer.putLong(count);
- buffer.putLongLong(size);
-}
-
-void QueuePolicy::decode ( Buffer& buffer )
-{
- maxCount = buffer.getLong();
- maxSize = buffer.getLongLong();
- count = buffer.getLong();
- size = buffer.getLongLong();
-}
-
-
-uint32_t QueuePolicy::encodedSize() const {
- return sizeof(uint32_t) + // maxCount
- sizeof(uint64_t) + // maxSize
- sizeof(uint32_t) + // count
- sizeof(uint64_t); // size
-}
-
-
-
-const std::string QueuePolicy::maxCountKey("qpid.max_count");
-const std::string QueuePolicy::maxSizeKey("qpid.max_size");
-const std::string QueuePolicy::typeKey("qpid.policy_type");
-const std::string QueuePolicy::REJECT("reject");
-const std::string QueuePolicy::FLOW_TO_DISK("flow_to_disk");
-const std::string QueuePolicy::RING("ring");
-const std::string QueuePolicy::RING_STRICT("ring_strict");
-uint64_t QueuePolicy::defaultMaxSize(0);
-
-FlowToDiskPolicy::FlowToDiskPolicy(const std::string& _name, uint32_t _maxCount, uint64_t _maxSize) :
- QueuePolicy(_name, _maxCount, _maxSize, FLOW_TO_DISK) {}
-
-bool FlowToDiskPolicy::checkLimit(boost::intrusive_ptr<Message> m)
-{
- if (!QueuePolicy::checkLimit(m)) m->requestContentRelease();
- return true;
-}
-
-RingQueuePolicy::RingQueuePolicy(const std::string& _name,
- uint32_t _maxCount, uint64_t _maxSize, const std::string& _type) :
- QueuePolicy(_name, _maxCount, _maxSize, _type), strict(_type == RING_STRICT) {}
-
-bool before(const QueuedMessage& a, const QueuedMessage& b)
-{
- int priorityA = PriorityQueue::getPriority(a);
- int priorityB = PriorityQueue::getPriority(b);
- if (priorityA == priorityB) return a.position < b.position;
- else return priorityA < priorityB;
-}
-
-void RingQueuePolicy::enqueued(const QueuedMessage& m)
-{
- //need to insert in correct location based on position
- queue.insert(lower_bound(queue.begin(), queue.end(), m, before), m);
-}
-
-void RingQueuePolicy::dequeued(const QueuedMessage& m)
-{
- //find and remove m from queue
- if (find(m, pendingDequeues, true) || find(m, queue, true)) {
- //now update count and size
- QueuePolicy::dequeued(m);
- }
-}
-
-bool RingQueuePolicy::isEnqueued(const QueuedMessage& m)
-{
- //for non-strict ring policy, a message can be replaced (and
- //therefore dequeued) before it is accepted or released by
- //subscriber; need to detect this
- return find(m, pendingDequeues, false) || find(m, queue, false);
-}
-
-bool RingQueuePolicy::checkLimit(boost::intrusive_ptr<Message> m)
-{
-
- // If the message is bigger than the queue size, give up
- if (getMaxSize() && m->contentSize() > getMaxSize()) {
- QPID_LOG(debug, "Message too large for ring queue " << name
- << " [" << *this << "] "
- << ": message size = " << m->contentSize() << " bytes"
- << ": max queue size = " << getMaxSize() << " bytes");
- return false;
- }
-
- // if within limits, ok to accept
- if (QueuePolicy::checkLimit(m)) return true;
-
- // At this point, we've exceeded maxSize, maxCount, or both.
- //
- // If we've exceeded maxCount, we've exceeded it by 1, so
- // replacing the first message is sufficient. If we've exceeded
- // maxSize, we need to pop enough messages to get the space we
- // need.
-
- unsigned int haveSpace = getMaxSize() - getCurrentQueueSize();
-
- do {
- QueuedMessage oldest = queue.front();
-
- if (oldest.queue->acquire(oldest) || !strict) {
- queue.pop_front();
- pendingDequeues.push_back(oldest);
- QPID_LOG(debug, "Ring policy triggered in " << name
- << ": removed message " << oldest.position << " to make way for new message");
-
- haveSpace += oldest.payload->contentSize();
-
- } else {
- //in strict mode, if oldest message has been delivered (hence
- //cannot be acquired) but not yet acked, it should not be
- //removed and the attempted enqueue should fail
- QPID_LOG(debug, "Ring policy could not be triggered in " << name
- << ": oldest message (seq-no=" << oldest.position << ") has been delivered but not yet acknowledged or requeued");
- return false;
- }
- } while (haveSpace < m->contentSize());
-
-
- return true;
-}
-
-void RingQueuePolicy::getPendingDequeues(Messages& result)
-{
- result = pendingDequeues;
-}
-
-bool RingQueuePolicy::find(const QueuedMessage& m, Messages& q, bool remove)
-{
- for (Messages::iterator i = q.begin(); i != q.end(); i++) {
- if (i->payload == m.payload) {
- if (remove) q.erase(i);
- return true;
- }
- }
- return false;
-}
-
-std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type)
-{
- return createQueuePolicy("<unspecified>", maxCount, maxSize, type);
-}
-
-std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const qpid::framing::FieldTable& settings)
-{
- return createQueuePolicy("<unspecified>", settings);
-}
-
-std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const std::string& name, const qpid::framing::FieldTable& settings)
-{
- uint32_t maxCount = getCapacity(settings, maxCountKey, 0);
- uint32_t maxSize = getCapacity(settings, maxSizeKey, defaultMaxSize);
- if (maxCount || maxSize) {
- return createQueuePolicy(name, maxCount, maxSize, getType(settings));
- } else {
- return std::auto_ptr<QueuePolicy>();
- }
-}
-
-std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const std::string& name,
- uint32_t maxCount, uint64_t maxSize, const std::string& type)
-{
- if (type == RING || type == RING_STRICT) {
- return std::auto_ptr<QueuePolicy>(new RingQueuePolicy(name, maxCount, maxSize, type));
- } else if (type == FLOW_TO_DISK) {
- return std::auto_ptr<QueuePolicy>(new FlowToDiskPolicy(name, maxCount, maxSize));
- } else {
- return std::auto_ptr<QueuePolicy>(new QueuePolicy(name, maxCount, maxSize, type));
- }
-
-}
-
-namespace qpid {
- namespace broker {
-
-std::ostream& operator<<(std::ostream& out, const QueuePolicy& p)
-{
- if (p.maxSize) out << "size: max=" << p.maxSize << ", current=" << p.size;
- else out << "size: unlimited";
- out << "; ";
- if (p.maxCount) out << "count: max=" << p.maxCount << ", current=" << p.count;
- else out << "count: unlimited";
- out << "; type=" << p.type;
- return out;
-}
-
- }
-}
-
diff --git a/cpp/src/qpid/broker/QueuePolicy.h b/cpp/src/qpid/broker/QueuePolicy.h
deleted file mode 100644
index 3cdd63784d..0000000000
--- a/cpp/src/qpid/broker/QueuePolicy.h
+++ /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.
- *
- */
-#ifndef _QueuePolicy_
-#define _QueuePolicy_
-
-#include <deque>
-#include <iostream>
-#include <memory>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/AtomicValue.h"
-#include "qpid/sys/Mutex.h"
-
-namespace qpid {
-namespace broker {
-
-class QueuePolicy
-{
- static uint64_t defaultMaxSize;
-
- uint32_t maxCount;
- uint64_t maxSize;
- const std::string type;
- uint32_t count;
- uint64_t size;
- bool policyExceeded;
-
- static uint32_t getCapacity(const qpid::framing::FieldTable& settings, const std::string& key, uint32_t defaultValue);
-
- protected:
- uint64_t getCurrentQueueSize() const { return size; }
-
- public:
- typedef std::deque<QueuedMessage> Messages;
- static QPID_BROKER_EXTERN const std::string maxCountKey;
- static QPID_BROKER_EXTERN const std::string maxSizeKey;
- static QPID_BROKER_EXTERN const std::string typeKey;
- static QPID_BROKER_EXTERN const std::string REJECT;
- static QPID_BROKER_EXTERN const std::string FLOW_TO_DISK;
- static QPID_BROKER_EXTERN const std::string RING;
- static QPID_BROKER_EXTERN const std::string RING_STRICT;
-
- virtual ~QueuePolicy() {}
- QPID_BROKER_EXTERN void tryEnqueue(boost::intrusive_ptr<Message> msg);
- QPID_BROKER_EXTERN void recoverEnqueued(boost::intrusive_ptr<Message> msg);
- QPID_BROKER_EXTERN void enqueueAborted(boost::intrusive_ptr<Message> msg);
- virtual void enqueued(const QueuedMessage&);
- virtual void dequeued(const QueuedMessage&);
- virtual bool isEnqueued(const QueuedMessage&);
- QPID_BROKER_EXTERN void update(qpid::framing::FieldTable& settings);
- uint32_t getMaxCount() const { return maxCount; }
- uint64_t getMaxSize() const { return maxSize; }
- void encode(framing::Buffer& buffer) const;
- void decode ( framing::Buffer& buffer );
- uint32_t encodedSize() const;
- virtual void getPendingDequeues(Messages& result);
-
- static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(const std::string& name, const qpid::framing::FieldTable& settings);
- static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(const std::string& name, uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
- static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings);
- static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
- static std::string getType(const qpid::framing::FieldTable& settings);
- static void setDefaultMaxSize(uint64_t);
- friend QPID_BROKER_EXTERN std::ostream& operator<<(std::ostream&,
- const QueuePolicy&);
- protected:
- const std::string name;
-
- QueuePolicy(const std::string& name, uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
-
- virtual bool checkLimit(boost::intrusive_ptr<Message> msg);
- void enqueued(uint64_t size);
- void dequeued(uint64_t size);
-};
-
-
-class FlowToDiskPolicy : public QueuePolicy
-{
- public:
- FlowToDiskPolicy(const std::string& name, uint32_t maxCount, uint64_t maxSize);
- bool checkLimit(boost::intrusive_ptr<Message> msg);
-};
-
-class RingQueuePolicy : public QueuePolicy
-{
- public:
- RingQueuePolicy(const std::string& name, uint32_t maxCount, uint64_t maxSize, const std::string& type = RING);
- void enqueued(const QueuedMessage&);
- void dequeued(const QueuedMessage&);
- bool isEnqueued(const QueuedMessage&);
- bool checkLimit(boost::intrusive_ptr<Message> msg);
- void getPendingDequeues(Messages& result);
- private:
- Messages pendingDequeues;
- Messages queue;
- const bool strict;
-
- bool find(const QueuedMessage&, Messages&, bool remove);
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/QueueRegistry.cpp b/cpp/src/qpid/broker/QueueRegistry.cpp
deleted file mode 100644
index 135a3543d9..0000000000
--- a/cpp/src/qpid/broker/QueueRegistry.cpp
+++ /dev/null
@@ -1,127 +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.
- *
- */
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueueRegistry.h"
-#include "qpid/broker/QueueEvents.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/log/Statement.h"
-#include <sstream>
-#include <assert.h>
-
-using namespace qpid::broker;
-using namespace qpid::sys;
-using std::string;
-
-QueueRegistry::QueueRegistry(Broker* b) :
- counter(1), store(0), events(0), parent(0), lastNode(false), broker(b) {}
-
-QueueRegistry::~QueueRegistry(){}
-
-std::pair<Queue::shared_ptr, bool>
-QueueRegistry::declare(const string& declareName, bool durable,
- bool autoDelete, const OwnershipToken* owner,
- boost::shared_ptr<Exchange> alternate,
- const qpid::framing::FieldTable& arguments,
- bool recovering/*true if this declare is a
- result of recovering queue
- definition from persistente
- record*/)
-{
- RWlock::ScopedWlock locker(lock);
- string name = declareName.empty() ? generateName() : declareName;
- assert(!name.empty());
- QueueMap::iterator i = queues.find(name);
-
- if (i == queues.end()) {
- Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner, parent, broker));
- if (alternate) {
- queue->setAlternateExchange(alternate);//need to do this *before* create
- alternate->incAlternateUsers();
- }
- if (!recovering) {
- //apply settings & create persistent record if required
- queue->create(arguments);
- } else {
- //i.e. recovering a queue for which we already have a persistent record
- queue->configure(arguments);
- }
- queues[name] = queue;
- if (lastNode) queue->setLastNodeFailure();
-
- return std::pair<Queue::shared_ptr, bool>(queue, true);
- } else {
- return std::pair<Queue::shared_ptr, bool>(i->second, false);
- }
-}
-
-void QueueRegistry::destroyLH (const string& name){
- queues.erase(name);
-}
-
-void QueueRegistry::destroy (const string& name){
- RWlock::ScopedWlock locker(lock);
- destroyLH (name);
-}
-
-Queue::shared_ptr QueueRegistry::find(const string& name){
- RWlock::ScopedRlock locker(lock);
- QueueMap::iterator i = queues.find(name);
-
- if (i == queues.end()) {
- return Queue::shared_ptr();
- } else {
- return i->second;
- }
-}
-
-string QueueRegistry::generateName(){
- string name;
- do {
- std::stringstream ss;
- ss << "tmp_" << counter++;
- name = ss.str();
- // Thread safety: Private function, only called with lock held
- // so this is OK.
- } while(queues.find(name) != queues.end());
- return name;
-}
-
-void QueueRegistry::setStore (MessageStore* _store)
-{
- store = _store;
-}
-
-MessageStore* QueueRegistry::getStore() const {
- return store;
-}
-
-void QueueRegistry::updateQueueClusterState(bool _lastNode)
-{
- RWlock::ScopedRlock locker(lock);
- for (QueueMap::iterator i = queues.begin(); i != queues.end(); i++) {
- if (_lastNode){
- i->second->setLastNodeFailure();
- } else {
- i->second->clearLastNodeFailure();
- }
- }
- lastNode = _lastNode;
-}
diff --git a/cpp/src/qpid/broker/QueueRegistry.h b/cpp/src/qpid/broker/QueueRegistry.h
deleted file mode 100644
index 8a32a64f05..0000000000
--- a/cpp/src/qpid/broker/QueueRegistry.h
+++ /dev/null
@@ -1,151 +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.
- *
- */
-#ifndef _QueueRegistry_
-#define _QueueRegistry_
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/management/Manageable.h"
-#include "qpid/framing/FieldTable.h"
-#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <algorithm>
-#include <map>
-
-namespace qpid {
-namespace broker {
-
-class Queue;
-class QueueEvents;
-class Exchange;
-class OwnershipToken;
-class Broker;
-class MessageStore;
-
-/**
- * A registry of queues indexed by queue name.
- *
- * Queues are reference counted using shared_ptr to ensure that they
- * are deleted when and only when they are no longer in use.
- *
- */
-class QueueRegistry {
- public:
- QPID_BROKER_EXTERN QueueRegistry(Broker* b = 0);
- QPID_BROKER_EXTERN ~QueueRegistry();
-
- /**
- * Declare a queue.
- *
- * @return The queue and a boolean flag which is true if the queue
- * was created by this declare call false if it already existed.
- */
- QPID_BROKER_EXTERN std::pair<boost::shared_ptr<Queue>, bool> declare(
- const std::string& name,
- bool durable = false,
- bool autodelete = false,
- const OwnershipToken* owner = 0,
- boost::shared_ptr<Exchange> alternateExchange = boost::shared_ptr<Exchange>(),
- const qpid::framing::FieldTable& args = framing::FieldTable(),
- bool recovering = false);
-
- /**
- * Destroy the named queue.
- *
- * Note: if the queue is in use it is not actually destroyed until
- * all shared_ptrs to it are destroyed. During that time it is
- * possible that a new queue with the same name may be
- * created. This should not create any problems as the new and
- * old queues exist independently. The registry has
- * forgotten the old queue so there can be no confusion for
- * subsequent calls to find or declare with the same name.
- *
- */
- QPID_BROKER_EXTERN void destroy(const std::string& name);
- template <class Test> bool destroyIf(const std::string& name, Test test)
- {
- qpid::sys::RWlock::ScopedWlock locker(lock);
- if (test()) {
- destroyLH (name);
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Find the named queue. Return 0 if not found.
- */
- QPID_BROKER_EXTERN boost::shared_ptr<Queue> find(const std::string& name);
-
- /**
- * Generate unique queue name.
- */
- std::string generateName();
-
- /**
- * Set the store to use. May only be called once.
- */
- void setStore (MessageStore*);
-
- /**
- * Return the message store used.
- */
- MessageStore* getStore() const;
-
- /**
- * Register the manageable parent for declared queues
- */
- void setParent (management::Manageable* _parent) { parent = _parent; }
-
- /** Call f for each queue in the registry. */
- template <class F> void eachQueue(F f) const {
- qpid::sys::RWlock::ScopedRlock l(lock);
- for (QueueMap::const_iterator i = queues.begin(); i != queues.end(); ++i)
- f(i->second);
- }
-
- /**
- * Change queue mode when cluster size drops to 1 node, expands again
- * in practice allows flow queue to disk when last name to be exectuted
- */
- void updateQueueClusterState(bool lastNode);
-
-private:
- typedef std::map<std::string, boost::shared_ptr<Queue> > QueueMap;
- QueueMap queues;
- mutable qpid::sys::RWlock lock;
- int counter;
- MessageStore* store;
- QueueEvents* events;
- management::Manageable* parent;
- bool lastNode; //used to set mode on queue declare
- Broker* broker;
-
- //destroy impl that assumes lock is already held:
- void destroyLH (const std::string& name);
-};
-
-
-}} // namespace qpid::broker
-
-
-#endif
diff --git a/cpp/src/qpid/broker/QueuedMessage.h b/cpp/src/qpid/broker/QueuedMessage.h
deleted file mode 100644
index 35e48b11f3..0000000000
--- a/cpp/src/qpid/broker/QueuedMessage.h
+++ /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.
- *
- */
-#ifndef _QueuedMessage_
-#define _QueuedMessage_
-
-#include "qpid/broker/Message.h"
-
-namespace qpid {
-namespace broker {
-
-class Queue;
-
-struct QueuedMessage
-{
- boost::intrusive_ptr<Message> payload;
- framing::SequenceNumber position;
- Queue* queue;
-
- QueuedMessage() : queue(0) {}
- QueuedMessage(Queue* q, boost::intrusive_ptr<Message> msg, framing::SequenceNumber sn) :
- payload(msg), position(sn), queue(q) {}
- QueuedMessage(Queue* q) : queue(q) {}
-
-};
- inline bool operator<(const QueuedMessage& a, const QueuedMessage& b) { return a.position < b.position; }
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RateFlowcontrol.h b/cpp/src/qpid/broker/RateFlowcontrol.h
deleted file mode 100644
index 99f9d2c0c4..0000000000
--- a/cpp/src/qpid/broker/RateFlowcontrol.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef broker_RateFlowcontrol_h
-#define broker_RateFlowcontrol_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/sys/Time.h"
-#include "qpid/sys/IntegerTypes.h"
-
-#include <algorithm>
-
-namespace qpid {
-namespace broker {
-
-// Class to keep track of issuing flow control to make sure that the peer doesn't exceed
-// a given message rate
-//
-// Create the object with the target rate
-// Then call sendCredit() whenever credit is issued to the peer
-// Call receivedMessage() whenever a message is received, it returns the credit to issue.
-//
-// sentCredit() be sensibly called with a 0 parameter to indicate
-// that we sent credit but treat it as if the value was 0 (we may do this at the start of the connection
-// to allow our peer to send messages)
-//
-// receivedMessage() can be called with 0 to indicate that we've not received a message, but
-// tell me what credit I can send.
-class RateFlowcontrol {
- uint32_t rate; // messages per second
- uint32_t maxCredit; // max credit issued to client (issued at start)
- uint32_t requestedCredit;
- qpid::sys::AbsTime creditSent;
-
-public:
- RateFlowcontrol(uint32_t r) :
- rate(r),
- maxCredit(0),
- requestedCredit(0),
- creditSent(qpid::sys::FAR_FUTURE)
- {}
-
- uint32_t getRate() const {
- return rate;
- }
- void sentCredit(const qpid::sys::AbsTime& t, uint32_t credit);
- uint32_t receivedMessage(const qpid::sys::AbsTime& t, uint32_t msgs);
- uint32_t availableCredit(const qpid::sys::AbsTime& t);
- bool flowStopped() const;
-};
-
-inline void RateFlowcontrol::sentCredit(const qpid::sys::AbsTime& t, uint32_t credit) {
- // If the client isn't currently requesting credit (ie it's not sent us anything yet) then
- // this credit goes to the max credit held by the client (it can't go to reduce credit
- // less than 0)
- int32_t nextRequestedCredit = requestedCredit - credit;
- if ( nextRequestedCredit<0 ) {
- requestedCredit = 0;
- maxCredit -= nextRequestedCredit;
- } else {
- requestedCredit = nextRequestedCredit;
- }
- creditSent = t;
-}
-
-inline uint32_t RateFlowcontrol::availableCredit(const qpid::sys::AbsTime& t) {
- qpid::sys::Duration d(creditSent, t);
- // Could be -ve before first sentCredit
- int64_t toSend = std::min(rate * d / qpid::sys::TIME_SEC, static_cast<int64_t>(requestedCredit));
- return toSend > 0 ? toSend : 0;
-}
-
-inline uint32_t RateFlowcontrol::receivedMessage(const qpid::sys::AbsTime& t, uint32_t msgs) {
- requestedCredit +=msgs;
- // Don't send credit for every message, only send if more than 0.5s since last credit or
- // we've got less than .25 of the max left (heuristic)
- return requestedCredit*4 >= maxCredit*3 || qpid::sys::Duration(creditSent, t) >= 500*qpid::sys::TIME_MSEC
- ? availableCredit(t)
- : 0;
-}
-
-inline bool RateFlowcontrol::flowStopped() const {
- return requestedCredit >= maxCredit;
-}
-
-}}
-
-#endif // broker_RateFlowcontrol_h
diff --git a/cpp/src/qpid/broker/RateTracker.cpp b/cpp/src/qpid/broker/RateTracker.cpp
deleted file mode 100644
index 048349b658..0000000000
--- a/cpp/src/qpid/broker/RateTracker.cpp
+++ /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.
- *
- */
-#include "qpid/broker/RateTracker.h"
-
-using qpid::sys::AbsTime;
-using qpid::sys::Duration;
-using qpid::sys::TIME_SEC;
-
-namespace qpid {
-namespace broker {
-
-RateTracker::RateTracker() : currentCount(0), lastCount(0), lastTime(AbsTime::now()) {}
-
-RateTracker& RateTracker::operator++()
-{
- ++currentCount;
- return *this;
-}
-
-double RateTracker::sampleRatePerSecond()
-{
- int32_t increment = currentCount - lastCount;
- AbsTime now = AbsTime::now();
- Duration interval(lastTime, now);
- lastCount = currentCount;
- lastTime = now;
- //if sampling at higher frequency than supported, will just return the number of increments
- if (interval < TIME_SEC) return increment;
- else if (increment == 0) return 0;
- else return increment / (interval / TIME_SEC);
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/RateTracker.h b/cpp/src/qpid/broker/RateTracker.h
deleted file mode 100644
index 0c20b37312..0000000000
--- a/cpp/src/qpid/broker/RateTracker.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef QPID_BROKER_RATETRACKER_H
-#define QPID_BROKER_RATETRACKER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/sys/Time.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Simple rate tracker: represents some value that can be incremented,
- * then can periodcially sample the rate of increments.
- */
-class RateTracker
-{
- public:
- RateTracker();
- /**
- * Increments the count being tracked. Can be called concurrently
- * with other calls to this operator as well as with calls to
- * sampleRatePerSecond().
- */
- RateTracker& operator++();
- /**
- * Returns the rate of increments per second since last
- * called. Calls to this method should be serialised, but can be
- * called concurrently with the increment operator
- */
- double sampleRatePerSecond();
- private:
- volatile int32_t currentCount;
- int32_t lastCount;
- qpid::sys::AbsTime lastTime;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_RATETRACKER_H*/
diff --git a/cpp/src/qpid/broker/RecoverableConfig.h b/cpp/src/qpid/broker/RecoverableConfig.h
deleted file mode 100644
index 838a8582dc..0000000000
--- a/cpp/src/qpid/broker/RecoverableConfig.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef _broker_RecoverableConfig_h
-#define _broker_RecoverableConfig_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-/**
- * The interface through which configurations are recovered.
- */
-class RecoverableConfig
-{
-public:
- typedef boost::shared_ptr<RecoverableConfig> shared_ptr;
-
- virtual void setPersistenceId(uint64_t id) = 0;
- virtual ~RecoverableConfig() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoverableExchange.h b/cpp/src/qpid/broker/RecoverableExchange.h
deleted file mode 100644
index ca6cc1541e..0000000000
--- a/cpp/src/qpid/broker/RecoverableExchange.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _broker_RecoverableExchange_h
-#define _broker_RecoverableExchange_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/shared_ptr.hpp>
-#include "qpid/framing/FieldTable.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * The interface through which bindings are recovered.
- */
-class RecoverableExchange
-{
-public:
- typedef boost::shared_ptr<RecoverableExchange> shared_ptr;
-
- virtual void setPersistenceId(uint64_t id) = 0;
- /**
- * Recover binding. Nb: queue must have been recovered earlier.
- */
- virtual void bind(const std::string& queue,
- const std::string& routingKey,
- qpid::framing::FieldTable& args) = 0;
- virtual ~RecoverableExchange() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoverableMessage.h b/cpp/src/qpid/broker/RecoverableMessage.h
deleted file mode 100644
index c98857ceb0..0000000000
--- a/cpp/src/qpid/broker/RecoverableMessage.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef _broker_RecoverableMessage_h
-#define _broker_RecoverableMessage_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/shared_ptr.hpp>
-#include "qpid/framing/amqp_types.h"
-#include "qpid/framing/Buffer.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * The interface through which messages are reloaded on recovery.
- */
-class RecoverableMessage
-{
-public:
- typedef boost::shared_ptr<RecoverableMessage> shared_ptr;
- virtual void setPersistenceId(uint64_t id) = 0;
- virtual void setRedelivered() = 0;
- /**
- * Used by store to determine whether to load content on recovery
- * or let message load its own content as and when it requires it.
- *
- * @returns true if the content of the message should be loaded
- */
- virtual bool loadContent(uint64_t available) = 0;
- /**
- * Loads the content held in the supplied buffer (may do checking
- * of length as necessary)
- */
- virtual void decodeContent(framing::Buffer& buffer) = 0;
- virtual ~RecoverableMessage() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoverableQueue.h b/cpp/src/qpid/broker/RecoverableQueue.h
deleted file mode 100644
index 49f05f97a1..0000000000
--- a/cpp/src/qpid/broker/RecoverableQueue.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef _broker_RecoverableQueue_h
-#define _broker_RecoverableQueue_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/RecoverableMessage.h"
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-class ExternalQueueStore;
-
-/**
- * The interface through which messages are added back to queues on
- * recovery.
- */
-class RecoverableQueue
-{
-public:
- typedef boost::shared_ptr<RecoverableQueue> shared_ptr;
-
- virtual void setPersistenceId(uint64_t id) = 0;
- virtual uint64_t getPersistenceId() const = 0;
- /**
- * Used during recovery to add stored messages back to the queue
- */
- virtual void recover(RecoverableMessage::shared_ptr msg) = 0;
- virtual ~RecoverableQueue() {};
-
- virtual const std::string& getName() const = 0;
- virtual void setExternalQueueStore(ExternalQueueStore* inst) = 0;
- virtual ExternalQueueStore* getExternalQueueStore() const = 0;
-
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoverableTransaction.h b/cpp/src/qpid/broker/RecoverableTransaction.h
deleted file mode 100644
index 1b7d94bd1a..0000000000
--- a/cpp/src/qpid/broker/RecoverableTransaction.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _broker_RecoverableTransaction_h
-#define _broker_RecoverableTransaction_h
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <boost/shared_ptr.hpp>
-
-#include "qpid/broker/RecoverableMessage.h"
-#include "qpid/broker/RecoverableQueue.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * The interface through which prepared 2pc transactions are
- * recovered.
- */
-class RecoverableTransaction
-{
-public:
- typedef boost::shared_ptr<RecoverableTransaction> shared_ptr;
- virtual void enqueue(RecoverableQueue::shared_ptr queue, RecoverableMessage::shared_ptr message) = 0;
- virtual void dequeue(RecoverableQueue::shared_ptr queue, RecoverableMessage::shared_ptr message) = 0;
- virtual ~RecoverableTransaction() {};
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoveredDequeue.cpp b/cpp/src/qpid/broker/RecoveredDequeue.cpp
deleted file mode 100644
index cd6735328f..0000000000
--- a/cpp/src/qpid/broker/RecoveredDequeue.cpp
+++ /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.
- *
- */
-
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/RecoveredDequeue.h"
-
-using boost::intrusive_ptr;
-using namespace qpid::broker;
-
-RecoveredDequeue::RecoveredDequeue(Queue::shared_ptr _queue, intrusive_ptr<Message> _msg) : queue(_queue), msg(_msg)
-{
- queue->recoverPrepared(msg);
-}
-
-bool RecoveredDequeue::prepare(TransactionContext*) throw()
-{
- //should never be called; transaction has already prepared if an enqueue is recovered
- return false;
-}
-
-void RecoveredDequeue::commit() throw()
-{
- queue->enqueueAborted(msg);
-}
-
-void RecoveredDequeue::rollback() throw()
-{
- queue->process(msg);
-}
-
diff --git a/cpp/src/qpid/broker/RecoveredDequeue.h b/cpp/src/qpid/broker/RecoveredDequeue.h
deleted file mode 100644
index 66e66f1d5f..0000000000
--- a/cpp/src/qpid/broker/RecoveredDequeue.h
+++ /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.
- *
- */
-#ifndef _RecoveredDequeue_
-#define _RecoveredDequeue_
-
-#include "qpid/broker/Deliverable.h"
-#include "qpid/broker/Message.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/TxOp.h"
-
-#include <boost/intrusive_ptr.hpp>
-
-#include <algorithm>
-#include <functional>
-#include <list>
-
-namespace qpid {
- namespace broker {
- class RecoveredDequeue : public TxOp{
- boost::shared_ptr<Queue> queue;
- boost::intrusive_ptr<Message> msg;
-
- public:
- RecoveredDequeue(boost::shared_ptr<Queue> queue, boost::intrusive_ptr<Message> msg);
- virtual bool prepare(TransactionContext* ctxt) throw();
- virtual void commit() throw();
- virtual void rollback() throw();
- virtual ~RecoveredDequeue(){}
- virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
-
- boost::shared_ptr<Queue> getQueue() const { return queue; }
- boost::intrusive_ptr<Message> getMessage() const { return msg; }
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoveredEnqueue.cpp b/cpp/src/qpid/broker/RecoveredEnqueue.cpp
deleted file mode 100644
index 6d2eaee6c4..0000000000
--- a/cpp/src/qpid/broker/RecoveredEnqueue.cpp
+++ /dev/null
@@ -1,45 +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.
- *
- */
-
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/RecoveredEnqueue.h"
-
-using boost::intrusive_ptr;
-using namespace qpid::broker;
-
-RecoveredEnqueue::RecoveredEnqueue(Queue::shared_ptr _queue, intrusive_ptr<Message> _msg) : queue(_queue), msg(_msg)
-{
- queue->recoverPrepared(msg);
-}
-
-bool RecoveredEnqueue::prepare(TransactionContext*) throw(){
- //should never be called; transaction has already prepared if an enqueue is recovered
- return false;
-}
-
-void RecoveredEnqueue::commit() throw(){
- queue->process(msg);
-}
-
-void RecoveredEnqueue::rollback() throw(){
- queue->enqueueAborted(msg);
-}
-
diff --git a/cpp/src/qpid/broker/RecoveredEnqueue.h b/cpp/src/qpid/broker/RecoveredEnqueue.h
deleted file mode 100644
index 5f718001d5..0000000000
--- a/cpp/src/qpid/broker/RecoveredEnqueue.h
+++ /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.
- *
- */
-#ifndef _RecoveredEnqueue_
-#define _RecoveredEnqueue_
-
-#include "qpid/broker/Deliverable.h"
-#include "qpid/broker/Message.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/TxOp.h"
-
-#include <boost/intrusive_ptr.hpp>
-
-#include <algorithm>
-#include <functional>
-#include <list>
-
-namespace qpid {
-namespace broker {
-class RecoveredEnqueue : public TxOp{
- boost::shared_ptr<Queue> queue;
- boost::intrusive_ptr<Message> msg;
-
- public:
- RecoveredEnqueue(boost::shared_ptr<Queue> queue, boost::intrusive_ptr<Message> msg);
- virtual bool prepare(TransactionContext* ctxt) throw();
- virtual void commit() throw();
- virtual void rollback() throw();
- virtual ~RecoveredEnqueue(){}
- virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
-
- boost::shared_ptr<Queue> getQueue() const { return queue; }
- boost::intrusive_ptr<Message> getMessage() const { return msg; }
-
-};
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoveryManager.h b/cpp/src/qpid/broker/RecoveryManager.h
deleted file mode 100644
index 2929e92250..0000000000
--- a/cpp/src/qpid/broker/RecoveryManager.h
+++ /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.
- *
- */
-#ifndef _RecoveryManager_
-#define _RecoveryManager_
-
-#include "qpid/broker/RecoverableExchange.h"
-#include "qpid/broker/RecoverableQueue.h"
-#include "qpid/broker/RecoverableMessage.h"
-#include "qpid/broker/RecoverableTransaction.h"
-#include "qpid/broker/RecoverableConfig.h"
-#include "qpid/broker/TransactionalStore.h"
-#include "qpid/framing/Buffer.h"
-
-namespace qpid {
-namespace broker {
-
-class RecoveryManager{
- public:
- virtual ~RecoveryManager(){}
- virtual RecoverableExchange::shared_ptr recoverExchange(framing::Buffer& buffer) = 0;
- virtual RecoverableQueue::shared_ptr recoverQueue(framing::Buffer& buffer) = 0;
- virtual RecoverableMessage::shared_ptr recoverMessage(framing::Buffer& buffer) = 0;
- virtual RecoverableTransaction::shared_ptr recoverTransaction(const std::string& xid,
- std::auto_ptr<TPCTransactionContext> txn) = 0;
- virtual RecoverableConfig::shared_ptr recoverConfig(framing::Buffer& buffer) = 0;
-
- virtual void recoveryComplete() = 0;
-};
-
-class Recoverable {
- public:
- virtual ~Recoverable() {}
-
- /**
- * Request recovery of queue and message state.
- */
- virtual void recover(RecoveryManager& recoverer) = 0;
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RecoveryManagerImpl.cpp b/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
deleted file mode 100644
index d08409695e..0000000000
--- a/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
+++ /dev/null
@@ -1,278 +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.
- *
- */
-#include "qpid/broker/RecoveryManagerImpl.h"
-
-#include "qpid/broker/Message.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/Link.h"
-#include "qpid/broker/Bridge.h"
-#include "qpid/broker/RecoveredEnqueue.h"
-#include "qpid/broker/RecoveredDequeue.h"
-#include "qpid/framing/reply_exceptions.h"
-
-using boost::dynamic_pointer_cast;
-using boost::intrusive_ptr;
-using std::string;
-
-namespace qpid {
-namespace broker {
-
-RecoveryManagerImpl::RecoveryManagerImpl(QueueRegistry& _queues, ExchangeRegistry& _exchanges, LinkRegistry& _links,
- DtxManager& _dtxMgr)
- : queues(_queues), exchanges(_exchanges), links(_links), dtxMgr(_dtxMgr) {}
-
-RecoveryManagerImpl::~RecoveryManagerImpl() {}
-
-class RecoverableMessageImpl : public RecoverableMessage
-{
- intrusive_ptr<Message> msg;
-public:
- RecoverableMessageImpl(const intrusive_ptr<Message>& _msg);
- ~RecoverableMessageImpl() {};
- void setPersistenceId(uint64_t id);
- void setRedelivered();
- bool loadContent(uint64_t available);
- void decodeContent(framing::Buffer& buffer);
- void recover(Queue::shared_ptr queue);
- void enqueue(DtxBuffer::shared_ptr buffer, Queue::shared_ptr queue);
- void dequeue(DtxBuffer::shared_ptr buffer, Queue::shared_ptr queue);
-};
-
-class RecoverableQueueImpl : public RecoverableQueue
-{
- Queue::shared_ptr queue;
-public:
- RecoverableQueueImpl(const boost::shared_ptr<Queue>& _queue) : queue(_queue) {}
- ~RecoverableQueueImpl() {};
- void setPersistenceId(uint64_t id);
- uint64_t getPersistenceId() const;
- const std::string& getName() const;
- void setExternalQueueStore(ExternalQueueStore* inst);
- ExternalQueueStore* getExternalQueueStore() const;
- void recover(RecoverableMessage::shared_ptr msg);
- void enqueue(DtxBuffer::shared_ptr buffer, RecoverableMessage::shared_ptr msg);
- void dequeue(DtxBuffer::shared_ptr buffer, RecoverableMessage::shared_ptr msg);
-};
-
-class RecoverableExchangeImpl : public RecoverableExchange
-{
- Exchange::shared_ptr exchange;
- QueueRegistry& queues;
-public:
- RecoverableExchangeImpl(Exchange::shared_ptr _exchange, QueueRegistry& _queues) : exchange(_exchange), queues(_queues) {}
- void setPersistenceId(uint64_t id);
- void bind(const std::string& queue, const std::string& routingKey, qpid::framing::FieldTable& args);
-};
-
-class RecoverableConfigImpl : public RecoverableConfig
-{
- Link::shared_ptr link;
- Bridge::shared_ptr bridge;
-public:
- RecoverableConfigImpl(Link::shared_ptr _link) : link(_link) {}
- RecoverableConfigImpl(Bridge::shared_ptr _bridge) : bridge(_bridge) {}
- void setPersistenceId(uint64_t id);
-};
-
-class RecoverableTransactionImpl : public RecoverableTransaction
-{
- DtxBuffer::shared_ptr buffer;
-public:
- RecoverableTransactionImpl(DtxBuffer::shared_ptr _buffer) : buffer(_buffer) {}
- void enqueue(RecoverableQueue::shared_ptr queue, RecoverableMessage::shared_ptr message);
- void dequeue(RecoverableQueue::shared_ptr queue, RecoverableMessage::shared_ptr message);
-};
-
-RecoverableExchange::shared_ptr RecoveryManagerImpl::recoverExchange(framing::Buffer& buffer)
-{
- Exchange::shared_ptr e = Exchange::decode(exchanges, buffer);
- if (e) {
- return RecoverableExchange::shared_ptr(new RecoverableExchangeImpl(e, queues));
- } else {
- return RecoverableExchange::shared_ptr();
- }
-}
-
-RecoverableQueue::shared_ptr RecoveryManagerImpl::recoverQueue(framing::Buffer& buffer)
-{
- Queue::shared_ptr queue = Queue::restore(queues, buffer);
- try {
- Exchange::shared_ptr exchange = exchanges.getDefault();
- if (exchange) {
- exchange->bind(queue, queue->getName(), 0);
- queue->bound(exchange->getName(), queue->getName(), framing::FieldTable());
- }
- } catch (const framing::NotFoundException& /*e*/) {
- //assume no default exchange has been declared
- }
- return RecoverableQueue::shared_ptr(new RecoverableQueueImpl(queue));
-}
-
-RecoverableMessage::shared_ptr RecoveryManagerImpl::recoverMessage(framing::Buffer& buffer)
-{
- boost::intrusive_ptr<Message> message(new Message());
- message->decodeHeader(buffer);
- return RecoverableMessage::shared_ptr(new RecoverableMessageImpl(message));
-}
-
-RecoverableTransaction::shared_ptr RecoveryManagerImpl::recoverTransaction(const std::string& xid,
- std::auto_ptr<TPCTransactionContext> txn)
-{
- DtxBuffer::shared_ptr buffer(new DtxBuffer());
- dtxMgr.recover(xid, txn, buffer);
- return RecoverableTransaction::shared_ptr(new RecoverableTransactionImpl(buffer));
-}
-
-RecoverableConfig::shared_ptr RecoveryManagerImpl::recoverConfig(framing::Buffer& buffer)
-{
- string kind;
-
- buffer.getShortString (kind);
- if (kind == "link")
- return RecoverableConfig::shared_ptr(new RecoverableConfigImpl(Link::decode (links, buffer)));
- else if (kind == "bridge")
- return RecoverableConfig::shared_ptr(new RecoverableConfigImpl(Bridge::decode (links, buffer)));
-
- return RecoverableConfig::shared_ptr(); // TODO: raise an exception instead
-}
-
-void RecoveryManagerImpl::recoveryComplete()
-{
- //notify all queues and exchanges
- queues.eachQueue(boost::bind(&Queue::recoveryComplete, _1, boost::ref(exchanges)));
- exchanges.eachExchange(boost::bind(&Exchange::recoveryComplete, _1, boost::ref(exchanges)));
-}
-
-RecoverableMessageImpl:: RecoverableMessageImpl(const intrusive_ptr<Message>& _msg) : msg(_msg)
-{
- if (!msg->isPersistent()) {
- msg->forcePersistent(); // set so that message will get dequeued from store.
- }
-}
-
-bool RecoverableMessageImpl::loadContent(uint64_t /*available*/)
-{
- return true;
-}
-
-void RecoverableMessageImpl::decodeContent(framing::Buffer& buffer)
-{
- msg->decodeContent(buffer);
-}
-
-void RecoverableMessageImpl::recover(Queue::shared_ptr queue)
-{
- queue->recover(msg);
-}
-
-void RecoverableMessageImpl::setPersistenceId(uint64_t id)
-{
- msg->setPersistenceId(id);
-}
-
-void RecoverableMessageImpl::setRedelivered()
-{
- msg->redeliver();
-}
-
-void RecoverableQueueImpl::recover(RecoverableMessage::shared_ptr msg)
-{
- dynamic_pointer_cast<RecoverableMessageImpl>(msg)->recover(queue);
-}
-
-void RecoverableQueueImpl::setPersistenceId(uint64_t id)
-{
- queue->setPersistenceId(id);
-}
-
-uint64_t RecoverableQueueImpl::getPersistenceId() const
-{
- return queue->getPersistenceId();
-}
-
-const std::string& RecoverableQueueImpl::getName() const
-{
- return queue->getName();
-}
-
-void RecoverableQueueImpl::setExternalQueueStore(ExternalQueueStore* inst)
-{
- queue->setExternalQueueStore(inst);
-}
-
-ExternalQueueStore* RecoverableQueueImpl::getExternalQueueStore() const
-{
- return queue->getExternalQueueStore();
-}
-
-void RecoverableExchangeImpl::setPersistenceId(uint64_t id)
-{
- exchange->setPersistenceId(id);
-}
-
-void RecoverableConfigImpl::setPersistenceId(uint64_t id)
-{
- if (link.get())
- link->setPersistenceId(id);
- else if (bridge.get())
- bridge->setPersistenceId(id);
-}
-
-void RecoverableExchangeImpl::bind(const string& queueName,
- const string& key,
- framing::FieldTable& args)
-{
- Queue::shared_ptr queue = queues.find(queueName);
- exchange->bind(queue, key, &args);
- queue->bound(exchange->getName(), key, args);
-}
-
-void RecoverableMessageImpl::dequeue(DtxBuffer::shared_ptr buffer, Queue::shared_ptr queue)
-{
- buffer->enlist(TxOp::shared_ptr(new RecoveredDequeue(queue, msg)));
-}
-
-void RecoverableMessageImpl::enqueue(DtxBuffer::shared_ptr buffer, Queue::shared_ptr queue)
-{
- buffer->enlist(TxOp::shared_ptr(new RecoveredEnqueue(queue, msg)));
-}
-
-void RecoverableQueueImpl::dequeue(DtxBuffer::shared_ptr buffer, RecoverableMessage::shared_ptr message)
-{
- dynamic_pointer_cast<RecoverableMessageImpl>(message)->dequeue(buffer, queue);
-}
-
-void RecoverableQueueImpl::enqueue(DtxBuffer::shared_ptr buffer, RecoverableMessage::shared_ptr message)
-{
- dynamic_pointer_cast<RecoverableMessageImpl>(message)->enqueue(buffer, queue);
-}
-
-void RecoverableTransactionImpl::dequeue(RecoverableQueue::shared_ptr queue, RecoverableMessage::shared_ptr message)
-{
- dynamic_pointer_cast<RecoverableQueueImpl>(queue)->dequeue(buffer, message);
-}
-
-void RecoverableTransactionImpl::enqueue(RecoverableQueue::shared_ptr queue, RecoverableMessage::shared_ptr message)
-{
- dynamic_pointer_cast<RecoverableQueueImpl>(queue)->enqueue(buffer, message);
-}
-
-}}
diff --git a/cpp/src/qpid/broker/RecoveryManagerImpl.h b/cpp/src/qpid/broker/RecoveryManagerImpl.h
deleted file mode 100644
index 1ad7892b13..0000000000
--- a/cpp/src/qpid/broker/RecoveryManagerImpl.h
+++ /dev/null
@@ -1,58 +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.
- *
- */
-#ifndef _RecoveryManagerImpl_
-#define _RecoveryManagerImpl_
-
-#include <list>
-#include "qpid/broker/DtxManager.h"
-#include "qpid/broker/ExchangeRegistry.h"
-#include "qpid/broker/QueueRegistry.h"
-#include "qpid/broker/LinkRegistry.h"
-#include "qpid/broker/RecoveryManager.h"
-
-namespace qpid {
-namespace broker {
-
- class RecoveryManagerImpl : public RecoveryManager{
- QueueRegistry& queues;
- ExchangeRegistry& exchanges;
- LinkRegistry& links;
- DtxManager& dtxMgr;
- public:
- RecoveryManagerImpl(QueueRegistry& queues, ExchangeRegistry& exchanges, LinkRegistry& links,
- DtxManager& dtxMgr);
- ~RecoveryManagerImpl();
-
- RecoverableExchange::shared_ptr recoverExchange(framing::Buffer& buffer);
- RecoverableQueue::shared_ptr recoverQueue(framing::Buffer& buffer);
- RecoverableMessage::shared_ptr recoverMessage(framing::Buffer& buffer);
- RecoverableTransaction::shared_ptr recoverTransaction(const std::string& xid,
- std::auto_ptr<TPCTransactionContext> txn);
- RecoverableConfig::shared_ptr recoverConfig(framing::Buffer& buffer);
- void recoveryComplete();
- };
-
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/RetryList.cpp b/cpp/src/qpid/broker/RetryList.cpp
deleted file mode 100644
index b0477dd0f7..0000000000
--- a/cpp/src/qpid/broker/RetryList.cpp
+++ /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.
- *
- */
-#include "qpid/broker/RetryList.h"
-
-namespace qpid {
-namespace broker {
-
-RetryList::RetryList() : urlIndex(0), addressIndex(0) {}
-
-void RetryList::reset(const std::vector<Url>& u)
-{
- urls = u;
- urlIndex = addressIndex = 0;//reset indices
-}
-
-bool RetryList::next(Address& address)
-{
- while (urlIndex < urls.size()) {
- if (addressIndex < urls[urlIndex].size()) {
- address = urls[urlIndex][addressIndex++];
- return true;
- }
- urlIndex++;
- addressIndex = 0;
- }
- urlIndex = addressIndex = 0;//reset indices
- return false;
-}
-
-std::ostream& operator<<(std::ostream& os, const RetryList& l)
-{
- for (size_t i = 0; i < l.urls.size(); i++) {
- os << l.urls[i] << " ";
- }
- return os;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/RetryList.h b/cpp/src/qpid/broker/RetryList.h
deleted file mode 100644
index 242a7d2122..0000000000
--- a/cpp/src/qpid/broker/RetryList.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef QPID_BROKER_RETRYLIST_H
-#define QPID_BROKER_RETRYLIST_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/Address.h"
-#include "qpid/Url.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Simple utility for managing a list of urls to try on reconnecting a
- * link. Currently only supports TCP urls.
- */
-class RetryList
-{
- public:
- QPID_BROKER_EXTERN RetryList();
- QPID_BROKER_EXTERN void reset(const std::vector<Url>& urls);
- QPID_BROKER_EXTERN bool next(Address& address);
- private:
- std::vector<Url> urls;
- size_t urlIndex;
- size_t addressIndex;
-
- friend std::ostream& operator<<(std::ostream& os, const RetryList& l);
-};
-
-std::ostream& operator<<(std::ostream& os, const RetryList& l);
-
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_RETRYLIST_H*/
diff --git a/cpp/src/qpid/broker/SaslAuthenticator.cpp b/cpp/src/qpid/broker/SaslAuthenticator.cpp
deleted file mode 100644
index acdb4934d4..0000000000
--- a/cpp/src/qpid/broker/SaslAuthenticator.cpp
+++ /dev/null
@@ -1,467 +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.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "qpid/broker/Connection.h"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/sys/SecuritySettings.h"
-#include <boost/format.hpp>
-
-#if HAVE_SASL
-#include <sasl/sasl.h>
-#include "qpid/sys/cyrus/CyrusSecurityLayer.h"
-using qpid::sys::cyrus::CyrusSecurityLayer;
-#endif
-
-using namespace qpid::framing;
-using qpid::sys::SecurityLayer;
-using qpid::sys::SecuritySettings;
-using boost::format;
-using boost::str;
-
-
-namespace qpid {
-namespace broker {
-
-
-
-class NullAuthenticator : public SaslAuthenticator
-{
- Connection& connection;
- framing::AMQP_ClientProxy::Connection client;
- std::string realm;
- const bool encrypt;
-public:
- NullAuthenticator(Connection& connection, bool encrypt);
- ~NullAuthenticator();
- void getMechanisms(framing::Array& mechanisms);
- void start(const std::string& mechanism, const std::string& response);
- void step(const std::string&) {}
- std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
-};
-
-#if HAVE_SASL
-
-
-
-class CyrusAuthenticator : public SaslAuthenticator
-{
- sasl_conn_t *sasl_conn;
- Connection& connection;
- framing::AMQP_ClientProxy::Connection client;
- const bool encrypt;
-
- void processAuthenticationStep(int code, const char *challenge, unsigned int challenge_len);
- bool getUsername(std::string& uid);
-
-public:
- CyrusAuthenticator(Connection& connection, bool encrypt);
- ~CyrusAuthenticator();
- void init();
- void getMechanisms(framing::Array& mechanisms);
- void start(const std::string& mechanism, const std::string& response);
- void step(const std::string& response);
- void getError(std::string& error);
- void getUid(std::string& uid) { getUsername(uid); }
- std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
-};
-
-bool SaslAuthenticator::available(void) {
- return true;
-}
-
-// Initialize the SASL mechanism; throw if it fails.
-void SaslAuthenticator::init(const std::string& saslName, std::string const & saslConfigPath )
-{
- // Check if we have a version of SASL that supports sasl_set_path()
-#if (SASL_VERSION_FULL >= ((2<<16)|(1<<8)|22))
- // If we are not given a sasl path, do nothing and allow the default to be used.
- if ( ! saslConfigPath.empty() ) {
- int code = sasl_set_path(SASL_PATH_TYPE_CONFIG,
- const_cast<char *>(saslConfigPath.c_str()));
- if(SASL_OK != code)
- throw Exception(QPID_MSG("SASL: sasl_set_path failed [" << code << "] " ));
- QPID_LOG(info, "SASL: config path set to " << saslConfigPath );
- }
-#endif
-
- int code = sasl_server_init(NULL, saslName.c_str());
- if (code != SASL_OK) {
- // TODO: Figure out who owns the char* returned by
- // sasl_errstring, though it probably does not matter much
- throw Exception(sasl_errstring(code, NULL, NULL));
- }
-}
-
-void SaslAuthenticator::fini(void)
-{
- sasl_done();
-}
-
-#else
-
-typedef NullAuthenticator CyrusAuthenticator;
-
-bool SaslAuthenticator::available(void) {
- return false;
-}
-
-void SaslAuthenticator::init(const std::string& /*saslName*/, std::string const & /*saslConfigPath*/ )
-{
- throw Exception("Requested authentication but SASL unavailable");
-}
-
-void SaslAuthenticator::fini(void)
-{
- return;
-}
-
-#endif
-
-std::auto_ptr<SaslAuthenticator> SaslAuthenticator::createAuthenticator(Connection& c, bool isShadow )
-{
- if (c.getBroker().getOptions().auth) {
- if ( isShadow )
- return std::auto_ptr<SaslAuthenticator>(new NullAuthenticator(c, c.getBroker().getOptions().requireEncrypted));
- else
- return std::auto_ptr<SaslAuthenticator>(new CyrusAuthenticator(c, c.getBroker().getOptions().requireEncrypted));
- } else {
- QPID_LOG(debug, "SASL: No Authentication Performed");
- return std::auto_ptr<SaslAuthenticator>(new NullAuthenticator(c, c.getBroker().getOptions().requireEncrypted));
- }
-}
-
-
-NullAuthenticator::NullAuthenticator(Connection& c, bool e) : connection(c), client(c.getOutput()),
- realm(c.getBroker().getOptions().realm), encrypt(e) {}
-NullAuthenticator::~NullAuthenticator() {}
-
-void NullAuthenticator::getMechanisms(Array& mechanisms)
-{
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("ANONYMOUS")));
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("PLAIN")));//useful for testing
-}
-
-void NullAuthenticator::start(const string& mechanism, const string& response)
-{
- if (encrypt) {
-#if HAVE_SASL
- // encryption required - check to see if we are running over an
- // encrypted SSL connection.
- SecuritySettings external = connection.getExternalSecuritySettings();
- sasl_ssf_t external_ssf = (sasl_ssf_t) external.ssf;
- if (external_ssf < 1) // < 1 == unencrypted
-#endif
- {
- QPID_LOG(error, "Rejected un-encrypted connection.");
- throw ConnectionForcedException("Connection must be encrypted.");
- }
- }
- if (mechanism == "PLAIN") { // Old behavior
- if (response.size() > 0) {
- string uid;
- string::size_type i = response.find((char)0);
- if (i == 0 && response.size() > 1) {
- //no authorization id; use authentication id
- i = response.find((char)0, 1);
- if (i != string::npos) uid = response.substr(1, i-1);
- } else if (i != string::npos) {
- //authorization id is first null delimited field
- uid = response.substr(0, i);
- }//else not a valid SASL PLAIN response, throw error?
- if (!uid.empty()) {
- //append realm if it has not already been added
- i = uid.find(realm);
- if (i == string::npos || realm.size() + i < uid.size()) {
- uid = str(format("%1%@%2%") % uid % realm);
- }
- connection.setUserId(uid);
- }
- }
- } else {
- connection.setUserId("anonymous");
- }
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, connection.getHeartbeatMax());
-}
-
-
-std::auto_ptr<SecurityLayer> NullAuthenticator::getSecurityLayer(uint16_t)
-{
- std::auto_ptr<SecurityLayer> securityLayer;
- return securityLayer;
-}
-
-
-#if HAVE_SASL
-
-CyrusAuthenticator::CyrusAuthenticator(Connection& c, bool _encrypt) :
- sasl_conn(0), connection(c), client(c.getOutput()), encrypt(_encrypt)
-{
- init();
-}
-
-void CyrusAuthenticator::init()
-{
- /* Next to the service name, which specifies the
- * /etc/sasl2/<service name>.conf file to read, the realm is
- * currently the most important argument below. When
- * performing authentication the user that is authenticating
- * will be looked up in a specific realm. If none is given
- * then the realm defaults to the hostname, which can cause
- * confusion when the daemon is run on different hosts that
- * may be logically sharing a realm (aka a user domain). This
- * is especially important for SASL PLAIN authentication,
- * which cannot specify a realm for the user that is
- * authenticating.
- */
- int code;
-
- const char *realm = connection.getBroker().getOptions().realm.c_str();
- code = sasl_server_new(BROKER_SASL_NAME, /* Service name */
- NULL, /* Server FQDN, gethostname() */
- realm, /* Authentication realm */
- NULL, /* Local IP, needed for some mechanism */
- NULL, /* Remote IP, needed for some mechanism */
- NULL, /* Callbacks */
- 0, /* Connection flags */
- &sasl_conn);
-
- if (SASL_OK != code) {
- QPID_LOG(error, "SASL: Connection creation failed: [" << code << "] " << sasl_errdetail(sasl_conn));
-
- // TODO: Change this to an exception signaling
- // server error, when one is available
- throw ConnectionForcedException("Unable to perform authentication");
- }
-
- sasl_security_properties_t secprops;
-
- //TODO: should the actual SSF values be configurable here?
- secprops.min_ssf = encrypt ? 10: 0;
- secprops.max_ssf = 256;
-
- // If the transport provides encryption, notify the SASL library of
- // the key length and set the ssf range to prevent double encryption.
- SecuritySettings external = connection.getExternalSecuritySettings();
- QPID_LOG(debug, "External ssf=" << external.ssf << " and auth=" << external.authid);
- sasl_ssf_t external_ssf = (sasl_ssf_t) external.ssf;
- if (external_ssf) {
- int result = sasl_setprop(sasl_conn, SASL_SSF_EXTERNAL, &external_ssf);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL error: unable to set external SSF: " << result));
- }
-
- secprops.max_ssf = secprops.min_ssf = 0;
- }
-
- QPID_LOG(debug, "min_ssf: " << secprops.min_ssf <<
- ", max_ssf: " << secprops.max_ssf <<
- ", external_ssf: " << external_ssf );
-
- if (!external.authid.empty()) {
- const char* external_authid = external.authid.c_str();
- int result = sasl_setprop(sasl_conn, SASL_AUTH_EXTERNAL, external_authid);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL error: unable to set external auth: " << result));
- }
-
- QPID_LOG(debug, "external auth detected and set to " << external_authid);
- }
-
- secprops.maxbufsize = 65535;
- secprops.property_names = 0;
- secprops.property_values = 0;
- secprops.security_flags = 0; /* or SASL_SEC_NOANONYMOUS etc as appropriate */
- /*
- * The nodict flag restricts SASL authentication mechanisms
- * to those that are not susceptible to dictionary attacks.
- * They are:
- * SRP
- * PASSDSS-3DES-1
- * EXTERNAL
- */
- if (external.nodict) secprops.security_flags |= SASL_SEC_NODICTIONARY;
- int result = sasl_setprop(sasl_conn, SASL_SEC_PROPS, &secprops);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL error: " << result));
- }
-}
-
-CyrusAuthenticator::~CyrusAuthenticator()
-{
- if (sasl_conn) {
- sasl_dispose(&sasl_conn);
- sasl_conn = 0;
- }
-}
-
-void CyrusAuthenticator::getError(string& error)
-{
- error = string(sasl_errdetail(sasl_conn));
-}
-
-bool CyrusAuthenticator::getUsername(string& uid)
-{
- const void* ptr;
-
- int code = sasl_getprop(sasl_conn, SASL_USERNAME, &ptr);
- if (SASL_OK == code) {
- uid = string(const_cast<char*>(static_cast<const char*>(ptr)));
- return true;
- } else {
- QPID_LOG(warning, "Failed to retrieve sasl username");
- return false;
- }
-}
-
-void CyrusAuthenticator::getMechanisms(Array& mechanisms)
-{
- const char *separator = " ";
- const char *list;
- unsigned int list_len;
- int count;
-
- int code = sasl_listmech(sasl_conn, NULL,
- "", separator, "",
- &list, &list_len,
- &count);
-
- if (SASL_OK != code) {
- QPID_LOG(info, "SASL: Mechanism listing failed: " << sasl_errdetail(sasl_conn));
-
- // TODO: Change this to an exception signaling
- // server error, when one is available
- throw ConnectionForcedException("Mechanism listing failed");
- } else {
- string mechanism;
- unsigned int start;
- unsigned int end;
-
- QPID_LOG(info, "SASL: Mechanism list: " << list);
-
- end = 0;
- do {
- start = end;
-
- // Seek to end of next mechanism
- while (end < list_len && separator[0] != list[end])
- end++;
-
- // Record the mechanism
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value(string(list, start, end - start))));
- end++;
- } while (end < list_len);
- }
-}
-
-void CyrusAuthenticator::start(const string& mechanism, const string& response)
-{
- const char *challenge;
- unsigned int challenge_len;
-
- QPID_LOG(debug, "SASL: Starting authentication with mechanism: " << mechanism);
- int code = sasl_server_start(sasl_conn,
- mechanism.c_str(),
- response.c_str(), response.length(),
- &challenge, &challenge_len);
-
- processAuthenticationStep(code, challenge, challenge_len);
-}
-
-void CyrusAuthenticator::step(const string& response)
-{
- const char *challenge;
- unsigned int challenge_len;
-
- int code = sasl_server_step(sasl_conn,
- response.c_str(), response.length(),
- &challenge, &challenge_len);
-
- processAuthenticationStep(code, challenge, challenge_len);
-}
-
-void CyrusAuthenticator::processAuthenticationStep(int code, const char *challenge, unsigned int challenge_len)
-{
- if (SASL_OK == code) {
- std::string uid;
- if (!getUsername(uid)) {
- // TODO: Change this to an exception signaling
- // authentication failure, when one is available
- throw ConnectionForcedException("Authenticated username unavailable");
- }
- QPID_LOG(info, connection.getMgmtId() << " SASL: Authentication succeeded for: " << uid);
-
- connection.setUserId(uid);
-
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, connection.getHeartbeatMax());
- } else if (SASL_CONTINUE == code) {
- string challenge_str(challenge, challenge_len);
-
- QPID_LOG(debug, "SASL: sending challenge to client");
-
- client.secure(challenge_str);
- } else {
- std::string uid;
- if (!getUsername(uid)) {
- QPID_LOG(info, "SASL: Authentication failed (no username available):" << sasl_errdetail(sasl_conn));
- } else {
- QPID_LOG(info, "SASL: Authentication failed for " << uid << ":" << sasl_errdetail(sasl_conn));
- }
-
- // TODO: Change to more specific exceptions, when they are
- // available
- switch (code) {
- case SASL_NOMECH:
- throw ConnectionForcedException("Unsupported mechanism");
- break;
- case SASL_TRYAGAIN:
- throw ConnectionForcedException("Transient failure, try again");
- break;
- default:
- throw ConnectionForcedException("Authentication failed");
- break;
- }
- }
-}
-
-std::auto_ptr<SecurityLayer> CyrusAuthenticator::getSecurityLayer(uint16_t maxFrameSize)
-{
-
- const void* value(0);
- int result = sasl_getprop(sasl_conn, SASL_SSF, &value);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL error: " << sasl_errdetail(sasl_conn)));
- }
- uint ssf = *(reinterpret_cast<const unsigned*>(value));
- std::auto_ptr<SecurityLayer> securityLayer;
- if (ssf) {
- securityLayer = std::auto_ptr<SecurityLayer>(new CyrusSecurityLayer(sasl_conn, maxFrameSize));
- }
- return securityLayer;
-}
-
-#endif
-
-}}
diff --git a/cpp/src/qpid/broker/SaslAuthenticator.h b/cpp/src/qpid/broker/SaslAuthenticator.h
deleted file mode 100644
index cfbe1a0cd1..0000000000
--- a/cpp/src/qpid/broker/SaslAuthenticator.h
+++ /dev/null
@@ -1,64 +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.
- *
- */
-#ifndef _SaslAuthenticator_
-#define _SaslAuthenticator_
-
-
-#include "qpid/framing/amqp_types.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/SecurityLayer.h"
-#include <memory>
-#include <vector>
-#include <boost/bind.hpp>
-#include <boost/function.hpp>
-
-namespace qpid {
-namespace broker {
-
-class Connection;
-
-class SaslAuthenticator
-{
-public:
- virtual ~SaslAuthenticator() {}
- virtual void getMechanisms(framing::Array& mechanisms) = 0;
- virtual void start(const std::string& mechanism, const std::string& response) = 0;
- virtual void step(const std::string& response) = 0;
- virtual void getUid(std::string&) {}
- virtual bool getUsername(std::string&) { return false; };
- virtual void getError(std::string&) {}
- virtual std::auto_ptr<qpid::sys::SecurityLayer> getSecurityLayer(uint16_t maxFrameSize) = 0;
-
- static bool available(void);
-
- // Initialize the SASL mechanism; throw if it fails.
- static void init(const std::string& saslName, std::string const & saslConfigPath );
- static void fini(void);
-
- static std::auto_ptr<SaslAuthenticator> createAuthenticator(Connection& connection, bool isShadow);
-
- virtual void callUserIdCallbacks() { }
-};
-
-}}
-
-#endif
diff --git a/cpp/src/qpid/broker/SecureConnection.cpp b/cpp/src/qpid/broker/SecureConnection.cpp
deleted file mode 100644
index 5c1ebf3e8b..0000000000
--- a/cpp/src/qpid/broker/SecureConnection.cpp
+++ /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.
- *
- */
-#include "qpid/broker/SecureConnection.h"
-#include "qpid/sys/SecurityLayer.h"
-#include "qpid/framing/reply_exceptions.h"
-
-namespace qpid {
-namespace broker {
-
-using qpid::sys::SecurityLayer;
-
-SecureConnection::SecureConnection() : secured(false) {}
-
-size_t SecureConnection::decode(const char* buffer, size_t size)
-{
- if (!secured && securityLayer.get()) {
- //security layer comes into effect on first read after its
- //activated
- secured = true;
- }
- if (secured) {
- return securityLayer->decode(buffer, size);
- } else {
- return codec->decode(buffer, size);
- }
-}
-
-size_t SecureConnection::encode(const char* buffer, size_t size)
-{
- if (secured) {
- return securityLayer->encode(buffer, size);
- } else {
- return codec->encode(buffer, size);
- }
-}
-
-bool SecureConnection::canEncode()
-{
- if (secured) return securityLayer->canEncode();
- else return codec->canEncode();
-}
-
-void SecureConnection::closed()
-{
- codec->closed();
-}
-
-bool SecureConnection::isClosed() const
-{
- return codec->isClosed();
-}
-
-framing::ProtocolVersion SecureConnection::getVersion() const
-{
- return codec->getVersion();
-}
-
-void SecureConnection:: setCodec(std::auto_ptr<ConnectionCodec> c)
-{
- codec = c;
-}
-
-void SecureConnection::activateSecurityLayer(std::auto_ptr<SecurityLayer> sl, bool secureImmediately)
-{
- securityLayer = sl;
- securityLayer->init(codec.get());
-
- if ( secureImmediately )
- secured = true;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SecureConnection.h b/cpp/src/qpid/broker/SecureConnection.h
deleted file mode 100644
index 1547faae1e..0000000000
--- a/cpp/src/qpid/broker/SecureConnection.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef QPID_BROKER_SECURECONNECTION_H
-#define QPID_BROKER_SECURECONNECTION_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/sys/ConnectionCodec.h"
-#include <memory>
-
-namespace qpid {
-
-namespace sys {
-class SecurityLayer;
-}
-
-namespace broker {
-
-/**
- * A ConnectionCodec 'wrapper' that allows a connection to be
- * 'secured' e.g. encrypted based on settings negotiatiated at the
- * time of establishment.
- */
-class SecureConnection : public qpid::sys::ConnectionCodec
-{
- public:
- SecureConnection();
- size_t decode(const char* buffer, size_t size);
- size_t encode(const char* buffer, size_t size);
- bool canEncode();
- void closed();
- bool isClosed() const;
- framing::ProtocolVersion getVersion() const;
- void setCodec(std::auto_ptr<ConnectionCodec>);
- void activateSecurityLayer(std::auto_ptr<qpid::sys::SecurityLayer>, bool secureImmediately=false);
- private:
- std::auto_ptr<ConnectionCodec> codec;
- std::auto_ptr<qpid::sys::SecurityLayer> securityLayer;
- bool secured;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_SECURECONNECTION_H*/
diff --git a/cpp/src/qpid/broker/SecureConnectionFactory.cpp b/cpp/src/qpid/broker/SecureConnectionFactory.cpp
deleted file mode 100644
index 754b443c22..0000000000
--- a/cpp/src/qpid/broker/SecureConnectionFactory.cpp
+++ /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.
- *
- */
-#include "qpid/broker/SecureConnectionFactory.h"
-#include "qpid/framing/ProtocolVersion.h"
-#include "qpid/amqp_0_10/Connection.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/broker/SecureConnection.h"
-#include "qpid/sys/SecuritySettings.h"
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace broker {
-
-using framing::ProtocolVersion;
-using qpid::sys::SecuritySettings;
-typedef std::auto_ptr<amqp_0_10::Connection> CodecPtr;
-typedef std::auto_ptr<SecureConnection> SecureConnectionPtr;
-typedef std::auto_ptr<Connection> ConnectionPtr;
-typedef std::auto_ptr<sys::ConnectionInputHandler> InputPtr;
-
-SecureConnectionFactory::SecureConnectionFactory(Broker& b) : broker(b) {}
-
-sys::ConnectionCodec*
-SecureConnectionFactory::create(ProtocolVersion v, sys::OutputControl& out, const std::string& id,
- const SecuritySettings& external) {
- if (broker.getConnectionCounter().allowConnection())
- {
- QPID_LOG(error, "Client max connection count limit exceeded: " << broker.getOptions().maxConnections << " connection refused");
- return 0;
- }
- if (v == ProtocolVersion(0, 10)) {
- SecureConnectionPtr sc(new SecureConnection());
- CodecPtr c(new amqp_0_10::Connection(out, id, false));
- ConnectionPtr i(new broker::Connection(c.get(), broker, id, external, false));
- i->setSecureConnection(sc.get());
- c->setInputHandler(InputPtr(i.release()));
- sc->setCodec(std::auto_ptr<sys::ConnectionCodec>(c));
- return sc.release();
- }
- return 0;
-}
-
-sys::ConnectionCodec*
-SecureConnectionFactory::create(sys::OutputControl& out, const std::string& id,
- const SecuritySettings& external) {
- // used to create connections from one broker to another
- SecureConnectionPtr sc(new SecureConnection());
- CodecPtr c(new amqp_0_10::Connection(out, id, true));
- ConnectionPtr i(new broker::Connection(c.get(), broker, id, external, true ));
- i->setSecureConnection(sc.get());
- c->setInputHandler(InputPtr(i.release()));
- sc->setCodec(std::auto_ptr<sys::ConnectionCodec>(c));
- return sc.release();
-}
-
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SecureConnectionFactory.h b/cpp/src/qpid/broker/SecureConnectionFactory.h
deleted file mode 100644
index 8a04dfcb15..0000000000
--- a/cpp/src/qpid/broker/SecureConnectionFactory.h
+++ /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.
- *
- */
-#ifndef _SecureConnectionFactory_
-#define _SecureConnectionFactory_
-
-#include "qpid/sys/ConnectionCodec.h"
-
-namespace qpid {
-namespace broker {
-class Broker;
-
-class SecureConnectionFactory : public sys::ConnectionCodec::Factory
-{
- public:
- SecureConnectionFactory(Broker& b);
-
- sys::ConnectionCodec*
- create(framing::ProtocolVersion, sys::OutputControl&, const std::string& id,
- const qpid::sys::SecuritySettings&);
-
- sys::ConnectionCodec*
- create(sys::OutputControl&, const std::string& id, const qpid::sys::SecuritySettings&);
-
- private:
- Broker& broker;
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/SemanticState.cpp b/cpp/src/qpid/broker/SemanticState.cpp
deleted file mode 100644
index ce86253f4a..0000000000
--- a/cpp/src/qpid/broker/SemanticState.cpp
+++ /dev/null
@@ -1,823 +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.
- *
- */
-
-#include "qpid/broker/SessionState.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/broker/DeliverableMessage.h"
-#include "qpid/broker/DtxAck.h"
-#include "qpid/broker/DtxTimeout.h"
-#include "qpid/broker/Message.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/SessionContext.h"
-#include "qpid/broker/SessionOutputException.h"
-#include "qpid/broker/TxAccept.h"
-#include "qpid/broker/TxPublish.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/framing/MessageTransferBody.h"
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/framing/IsInSequenceSet.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/ClusterSafe.h"
-#include "qpid/ptr_map.h"
-#include "qpid/broker/AclModule.h"
-
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-
-#include <iostream>
-#include <sstream>
-#include <algorithm>
-#include <functional>
-
-#include <assert.h>
-
-namespace qpid {
-namespace broker {
-
-using namespace std;
-using boost::intrusive_ptr;
-using boost::bind;
-using namespace qpid::broker;
-using namespace qpid::framing;
-using namespace qpid::sys;
-using qpid::ptr_map_ptr;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-SemanticState::SemanticState(DeliveryAdapter& da, SessionContext& ss)
- : session(ss),
- deliveryAdapter(da),
- tagGenerator("sgen"),
- dtxSelected(false),
- authMsg(getSession().getBroker().getOptions().auth && !getSession().getConnection().isFederationLink()),
- userID(getSession().getConnection().getUserId()),
- userName(getSession().getConnection().getUserId().substr(0,getSession().getConnection().getUserId().find('@'))),
- isDefaultRealm(userID.find('@') != std::string::npos && getSession().getBroker().getOptions().realm == userID.substr(userID.find('@')+1,userID.size())),
- closeComplete(false)
-{
- acl = getSession().getBroker().getAcl();
-}
-
-SemanticState::~SemanticState() {
- closed();
-}
-
-void SemanticState::closed() {
- if (!closeComplete) {
- //prevent requeued messages being redelivered to consumers
- for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
- disable(i->second);
- }
- if (dtxBuffer.get()) {
- dtxBuffer->fail();
- }
- recover(true);
-
- //now unsubscribe, which may trigger queue deletion and thus
- //needs to occur after the requeueing of unacked messages
- for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
- unsubscribe(i->second);
- }
- closeComplete = true;
- }
-}
-
-bool SemanticState::exists(const string& consumerTag){
- return consumers.find(consumerTag) != consumers.end();
-}
-
-void SemanticState::consume(const string& tag,
- Queue::shared_ptr queue, bool ackRequired, bool acquire,
- bool exclusive, const string& resumeId, uint64_t resumeTtl, const FieldTable& arguments)
-{
- ConsumerImpl::shared_ptr c(new ConsumerImpl(this, tag, queue, ackRequired, acquire, exclusive, resumeId, resumeTtl, arguments));
- queue->consume(c, exclusive);//may throw exception
- consumers[tag] = c;
-}
-
-bool SemanticState::cancel(const string& tag)
-{
- ConsumerImplMap::iterator i = consumers.find(tag);
- if (i != consumers.end()) {
- cancel(i->second);
- consumers.erase(i);
- //should cancel all unacked messages for this consumer so that
- //they are not redelivered on recovery
- for_each(unacked.begin(), unacked.end(), boost::bind(&DeliveryRecord::cancel, _1, tag));
- return true;
- } else {
- return false;
- }
-}
-
-
-void SemanticState::startTx()
-{
- txBuffer = TxBuffer::shared_ptr(new TxBuffer());
-}
-
-void SemanticState::commit(MessageStore* const store)
-{
- if (!txBuffer) throw
- CommandInvalidException(QPID_MSG("Session has not been selected for use with transactions"));
-
- TxOp::shared_ptr txAck(static_cast<TxOp*>(new TxAccept(accumulatedAck, unacked)));
- txBuffer->enlist(txAck);
- if (txBuffer->commitLocal(store)) {
- accumulatedAck.clear();
- } else {
- throw InternalErrorException(QPID_MSG("Commit failed"));
- }
-}
-
-void SemanticState::rollback()
-{
- if (!txBuffer)
- throw CommandInvalidException(QPID_MSG("Session has not been selected for use with transactions"));
-
- txBuffer->rollback();
- accumulatedAck.clear();
-}
-
-void SemanticState::selectDtx()
-{
- dtxSelected = true;
-}
-
-void SemanticState::startDtx(const std::string& xid, DtxManager& mgr, bool join)
-{
- if (!dtxSelected) {
- throw CommandInvalidException(QPID_MSG("Session has not been selected for use with dtx"));
- }
- dtxBuffer = DtxBuffer::shared_ptr(new DtxBuffer(xid));
- txBuffer = boost::static_pointer_cast<TxBuffer>(dtxBuffer);
- if (join) {
- mgr.join(xid, dtxBuffer);
- } else {
- mgr.start(xid, dtxBuffer);
- }
-}
-
-void SemanticState::endDtx(const std::string& xid, bool fail)
-{
- if (!dtxBuffer) {
- throw IllegalStateException(QPID_MSG("xid " << xid << " not associated with this session"));
- }
- if (dtxBuffer->getXid() != xid) {
- throw CommandInvalidException(
- QPID_MSG("xid specified on start was " << dtxBuffer->getXid() << ", but " << xid << " specified on end"));
-
- }
-
- txBuffer.reset();//ops on this session no longer transactional
-
- checkDtxTimeout();
- if (fail) {
- dtxBuffer->fail();
- } else {
- dtxBuffer->markEnded();
- }
- dtxBuffer.reset();
-}
-
-void SemanticState::suspendDtx(const std::string& xid)
-{
- if (dtxBuffer->getXid() != xid) {
- throw CommandInvalidException(
- QPID_MSG("xid specified on start was " << dtxBuffer->getXid() << ", but " << xid << " specified on suspend"));
- }
- txBuffer.reset();//ops on this session no longer transactional
-
- checkDtxTimeout();
- dtxBuffer->setSuspended(true);
- suspendedXids[xid] = dtxBuffer;
- dtxBuffer.reset();
-}
-
-void SemanticState::resumeDtx(const std::string& xid)
-{
- if (!dtxSelected) {
- throw CommandInvalidException(QPID_MSG("Session has not been selected for use with dtx"));
- }
-
- dtxBuffer = suspendedXids[xid];
- if (!dtxBuffer) {
- throw CommandInvalidException(QPID_MSG("xid " << xid << " not attached"));
- } else {
- suspendedXids.erase(xid);
- }
-
- if (dtxBuffer->getXid() != xid) {
- throw CommandInvalidException(
- QPID_MSG("xid specified on start was " << dtxBuffer->getXid() << ", but " << xid << " specified on resume"));
-
- }
- if (!dtxBuffer->isSuspended()) {
- throw CommandInvalidException(QPID_MSG("xid " << xid << " not suspended"));
- }
-
- checkDtxTimeout();
- dtxBuffer->setSuspended(false);
- txBuffer = boost::static_pointer_cast<TxBuffer>(dtxBuffer);
-}
-
-void SemanticState::checkDtxTimeout()
-{
- if (dtxBuffer->isExpired()) {
- dtxBuffer.reset();
- throw DtxTimeoutException();
- }
-}
-
-void SemanticState::record(const DeliveryRecord& delivery)
-{
- unacked.push_back(delivery);
-}
-
-const std::string QPID_SYNC_FREQUENCY("qpid.sync_frequency");
-
-SemanticState::ConsumerImpl::ConsumerImpl(SemanticState* _parent,
- const string& _name,
- Queue::shared_ptr _queue,
- bool ack,
- bool _acquire,
- bool _exclusive,
- const string& _resumeId,
- uint64_t _resumeTtl,
- const framing::FieldTable& _arguments
-
-
-) :
- Consumer(_acquire),
- parent(_parent),
- name(_name),
- queue(_queue),
- ackExpected(ack),
- acquire(_acquire),
- blocked(true),
- windowing(true),
- exclusive(_exclusive),
- resumeId(_resumeId),
- resumeTtl(_resumeTtl),
- arguments(_arguments),
- msgCredit(0),
- byteCredit(0),
- notifyEnabled(true),
- syncFrequency(_arguments.getAsInt(QPID_SYNC_FREQUENCY)),
- deliveryCount(0),
- mgmtObject(0)
-{
- if (parent != 0 && queue.get() != 0 && queue->GetManagementObject() !=0)
- {
- ManagementAgent* agent = parent->session.getBroker().getManagementAgent();
- qpid::management::Manageable* ms = dynamic_cast<qpid::management::Manageable*> (&(parent->session));
-
- if (agent != 0)
- {
- mgmtObject = new _qmf::Subscription(agent, this, ms , queue->GetManagementObject()->getObjectId() ,name,
- !acquire, ackExpected, exclusive, ManagementAgent::toMap(arguments));
- agent->addObject (mgmtObject);
- mgmtObject->set_creditMode("WINDOW");
- }
- }
-}
-
-ManagementObject* SemanticState::ConsumerImpl::GetManagementObject (void) const
-{
- return (ManagementObject*) mgmtObject;
-}
-
-Manageable::status_t SemanticState::ConsumerImpl::ManagementMethod (uint32_t methodId, Args&, string&)
-{
- Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD;
-
- QPID_LOG (debug, "Queue::ManagementMethod [id=" << methodId << "]");
-
- return status;
-}
-
-
-OwnershipToken* SemanticState::ConsumerImpl::getSession()
-{
- return &(parent->session);
-}
-
-bool SemanticState::ConsumerImpl::deliver(QueuedMessage& msg)
-{
- assertClusterSafe();
- allocateCredit(msg.payload);
- DeliveryRecord record(msg, queue, name, acquire, !ackExpected, windowing);
- bool sync = syncFrequency && ++deliveryCount >= syncFrequency;
- if (sync) deliveryCount = 0;//reset
- parent->deliver(record, sync);
- if (!ackExpected && acquire) record.setEnded();//allows message to be released now its been delivered
- if (windowing || ackExpected || !acquire) {
- parent->record(record);
- }
- if (acquire && !ackExpected) {
- queue->dequeue(0, msg);
- }
- if (mgmtObject) { mgmtObject->inc_delivered(); }
- return true;
-}
-
-bool SemanticState::ConsumerImpl::filter(intrusive_ptr<Message>)
-{
- return true;
-}
-
-bool SemanticState::ConsumerImpl::accept(intrusive_ptr<Message> msg)
-{
- assertClusterSafe();
- // FIXME aconway 2009-06-08: if we have byte & message credit but
- // checkCredit fails because the message is to big, we should
- // remain on queue's listener list for possible smaller messages
- // in future.
- //
- blocked = !(filter(msg) && checkCredit(msg));
- return !blocked;
-}
-
-namespace {
-struct ConsumerName {
- const SemanticState::ConsumerImpl& consumer;
- ConsumerName(const SemanticState::ConsumerImpl& ci) : consumer(ci) {}
-};
-
-ostream& operator<<(ostream& o, const ConsumerName& pc) {
- return o << pc.consumer.getName() << " on "
- << pc.consumer.getParent().getSession().getSessionId();
-}
-}
-
-void SemanticState::ConsumerImpl::allocateCredit(intrusive_ptr<Message>& msg)
-{
- assertClusterSafe();
- uint32_t originalMsgCredit = msgCredit;
- uint32_t originalByteCredit = byteCredit;
- if (msgCredit != 0xFFFFFFFF) {
- msgCredit--;
- }
- if (byteCredit != 0xFFFFFFFF) {
- byteCredit -= msg->getRequiredCredit();
- }
- QPID_LOG(debug, "Credit allocated for " << ConsumerName(*this)
- << ", was " << " bytes: " << originalByteCredit << " msgs: " << originalMsgCredit
- << " now bytes: " << byteCredit << " msgs: " << msgCredit);
-
-}
-
-bool SemanticState::ConsumerImpl::checkCredit(intrusive_ptr<Message>& msg)
-{
- bool enoughCredit = msgCredit > 0 &&
- (byteCredit == 0xFFFFFFFF || byteCredit >= msg->getRequiredCredit());
- QPID_LOG(debug, (enoughCredit ? "Sufficient credit for " : "Insufficient credit for ")
- << ConsumerName(*this)
- << ", have bytes: " << byteCredit << " msgs: " << msgCredit
- << ", need " << msg->getRequiredCredit() << " bytes");
- return enoughCredit;
-}
-
-SemanticState::ConsumerImpl::~ConsumerImpl()
-{
- if (mgmtObject != 0)
- mgmtObject->resourceDestroy ();
-}
-
-void SemanticState::disable(ConsumerImpl::shared_ptr c)
-{
- c->disableNotify();
- if (session.isAttached())
- session.getConnection().outputTasks.removeOutputTask(c.get());
-}
-
-void SemanticState::unsubscribe(ConsumerImpl::shared_ptr c)
-{
- Queue::shared_ptr queue = c->getQueue();
- if(queue) {
- queue->cancel(c);
- if (queue->canAutoDelete() && !queue->hasExclusiveOwner()) {
- Queue::tryAutoDelete(session.getBroker(), queue);
- }
- }
-}
-
-void SemanticState::cancel(ConsumerImpl::shared_ptr c)
-{
- disable(c);
- unsubscribe(c);
-}
-
-void SemanticState::handle(intrusive_ptr<Message> msg) {
- if (txBuffer.get()) {
- TxPublish* deliverable(new TxPublish(msg));
- TxOp::shared_ptr op(deliverable);
- route(msg, *deliverable);
- txBuffer->enlist(op);
- } else {
- DeliverableMessage deliverable(msg);
- route(msg, deliverable);
- if (msg->isContentReleaseRequested()) {
- // NOTE: The log messages in this section are used for flow-to-disk testing (which checks the log for the
- // presence of these messages). Do not change these without also checking these tests.
- if (msg->isContentReleaseBlocked()) {
- QPID_LOG(debug, "Message id=\"" << msg->getProperties<MessageProperties>()->getMessageId() << "\"; pid=0x" <<
- std::hex << msg->getPersistenceId() << std::dec << ": Content release blocked");
- } else {
- msg->releaseContent();
- QPID_LOG(debug, "Message id=\"" << msg->getProperties<MessageProperties>()->getMessageId() << "\"; pid=0x" <<
- std::hex << msg->getPersistenceId() << std::dec << ": Content released");
- }
- }
- }
-}
-
-namespace
-{
-const std::string nullstring;
-}
-
-void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) {
- msg->setTimestamp(getSession().getBroker().getExpiryPolicy());
-
- std::string exchangeName = msg->getExchangeName();
- if (!cacheExchange || cacheExchange->getName() != exchangeName || cacheExchange->isDestroyed())
- cacheExchange = session.getBroker().getExchanges().get(exchangeName);
- cacheExchange->setProperties(msg);
-
- /* verify the userid if specified: */
- std::string id =
- msg->hasProperties<MessageProperties>() ? msg->getProperties<MessageProperties>()->getUserId() : nullstring;
-
- if (authMsg && !id.empty() && !(id == userID || (isDefaultRealm && id == userName)))
- {
- QPID_LOG(debug, "authorised user id : " << userID << " but user id in message declared as " << id);
- throw UnauthorizedAccessException(QPID_MSG("authorised user id : " << userID << " but user id in message declared as " << id));
- }
-
- if (acl && acl->doTransferAcl())
- {
- if (!acl->authorise(getSession().getConnection().getUserId(),acl::ACT_PUBLISH,acl::OBJ_EXCHANGE,exchangeName, msg->getRoutingKey() ))
- throw UnauthorizedAccessException(QPID_MSG(userID << " cannot publish to " <<
- exchangeName << " with routing-key " << msg->getRoutingKey()));
- }
-
- cacheExchange->route(strategy, msg->getRoutingKey(), msg->getApplicationHeaders());
-
- if (!strategy.delivered) {
- //TODO:if discard-unroutable, just drop it
- //TODO:else if accept-mode is explicit, reject it
- //else route it to alternate exchange
- if (cacheExchange->getAlternate()) {
- cacheExchange->getAlternate()->route(strategy, msg->getRoutingKey(), msg->getApplicationHeaders());
- }
- if (!strategy.delivered) {
- msg->destroy();
- }
- }
-
-}
-
-void SemanticState::requestDispatch()
-{
- for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++)
- i->second->requestDispatch();
-}
-
-void SemanticState::ConsumerImpl::requestDispatch()
-{
- assertClusterSafe();
- if (blocked) {
- parent->session.getConnection().outputTasks.addOutputTask(this);
- parent->session.getConnection().outputTasks.activateOutput();
- blocked = false;
- }
-}
-
-bool SemanticState::complete(DeliveryRecord& delivery)
-{
- ConsumerImplMap::iterator i = consumers.find(delivery.getTag());
- if (i != consumers.end()) {
- i->second->complete(delivery);
- }
- return delivery.isRedundant();
-}
-
-void SemanticState::ConsumerImpl::complete(DeliveryRecord& delivery)
-{
- if (!delivery.isComplete()) {
- delivery.complete();
- if (windowing) {
- if (msgCredit != 0xFFFFFFFF) msgCredit++;
- if (byteCredit != 0xFFFFFFFF) byteCredit += delivery.getCredit();
- }
- }
-}
-
-void SemanticState::recover(bool requeue)
-{
- if(requeue){
- //take copy and clear unacked as requeue may result in redelivery to this session
- //which will in turn result in additions to unacked
- DeliveryRecords copy = unacked;
- unacked.clear();
- for_each(copy.rbegin(), copy.rend(), mem_fun_ref(&DeliveryRecord::requeue));
- }else{
- for_each(unacked.begin(), unacked.end(), boost::bind(&DeliveryRecord::redeliver, _1, this));
- //unconfirmed messages re redelivered and therefore have their
- //id adjusted, confirmed messages are not and so the ordering
- //w.r.t id is lost
- sort(unacked.begin(), unacked.end());
- }
-}
-
-void SemanticState::deliver(DeliveryRecord& msg, bool sync)
-{
- return deliveryAdapter.deliver(msg, sync);
-}
-
-SemanticState::ConsumerImpl& SemanticState::find(const std::string& destination)
-{
- ConsumerImplMap::iterator i = consumers.find(destination);
- if (i == consumers.end()) {
- throw NotFoundException(QPID_MSG("Unknown destination " << destination));
- } else {
- return *(i->second);
- }
-}
-
-void SemanticState::setWindowMode(const std::string& destination)
-{
- find(destination).setWindowMode();
-}
-
-void SemanticState::setCreditMode(const std::string& destination)
-{
- find(destination).setCreditMode();
-}
-
-void SemanticState::addByteCredit(const std::string& destination, uint32_t value)
-{
- ConsumerImpl& c = find(destination);
- c.addByteCredit(value);
- c.requestDispatch();
-}
-
-
-void SemanticState::addMessageCredit(const std::string& destination, uint32_t value)
-{
- ConsumerImpl& c = find(destination);
- c.addMessageCredit(value);
- c.requestDispatch();
-}
-
-void SemanticState::flush(const std::string& destination)
-{
- find(destination).flush();
-}
-
-
-void SemanticState::stop(const std::string& destination)
-{
- find(destination).stop();
-}
-
-void SemanticState::ConsumerImpl::setWindowMode()
-{
- assertClusterSafe();
- windowing = true;
- if (mgmtObject){
- mgmtObject->set_creditMode("WINDOW");
- }
-}
-
-void SemanticState::ConsumerImpl::setCreditMode()
-{
- assertClusterSafe();
- windowing = false;
- if (mgmtObject){
- mgmtObject->set_creditMode("CREDIT");
- }
-}
-
-void SemanticState::ConsumerImpl::addByteCredit(uint32_t value)
-{
- assertClusterSafe();
- if (byteCredit != 0xFFFFFFFF) {
- if (value == 0xFFFFFFFF) byteCredit = value;
- else byteCredit += value;
- }
-}
-
-void SemanticState::ConsumerImpl::addMessageCredit(uint32_t value)
-{
- assertClusterSafe();
- if (msgCredit != 0xFFFFFFFF) {
- if (value == 0xFFFFFFFF) msgCredit = value;
- else msgCredit += value;
- }
-}
-
-bool SemanticState::ConsumerImpl::haveCredit()
-{
- if (msgCredit && byteCredit) {
- return true;
- } else {
- blocked = true;
- return false;
- }
-}
-
-void SemanticState::ConsumerImpl::flush()
-{
- while(haveCredit() && queue->dispatch(shared_from_this()))
- ;
- stop();
-}
-
-void SemanticState::ConsumerImpl::stop()
-{
- assertClusterSafe();
- msgCredit = 0;
- byteCredit = 0;
-}
-
-Queue::shared_ptr SemanticState::getQueue(const string& name) const {
- Queue::shared_ptr queue;
- if (name.empty()) {
- throw NotAllowedException(QPID_MSG("No queue name specified."));
- } else {
- queue = session.getBroker().getQueues().find(name);
- if (!queue)
- throw NotFoundException(QPID_MSG("Queue not found: "<<name));
- }
- return queue;
-}
-
-AckRange SemanticState::findRange(DeliveryId first, DeliveryId last)
-{
- return DeliveryRecord::findRange(unacked, first, last);
-}
-
-void SemanticState::acquire(DeliveryId first, DeliveryId last, DeliveryIds& acquired)
-{
- AckRange range = findRange(first, last);
- for_each(range.start, range.end, AcquireFunctor(acquired));
-}
-
-void SemanticState::release(DeliveryId first, DeliveryId last, bool setRedelivered)
-{
- AckRange range = findRange(first, last);
- //release results in the message being added to the head so want
- //to release in reverse order to keep the original transfer order
- DeliveryRecords::reverse_iterator start(range.end);
- DeliveryRecords::reverse_iterator end(range.start);
- for_each(start, end, boost::bind(&DeliveryRecord::release, _1, setRedelivered));
-}
-
-void SemanticState::reject(DeliveryId first, DeliveryId last)
-{
- AckRange range = findRange(first, last);
- for_each(range.start, range.end, mem_fun_ref(&DeliveryRecord::reject));
- //may need to remove the delivery records as well
- for (DeliveryRecords::iterator i = range.start; i != unacked.end() && i->getId() <= last; ) {
- if (i->isRedundant()) i = unacked.erase(i);
- else i++;
- }
-}
-
-bool SemanticState::ConsumerImpl::doOutput()
-{
- try {
- return haveCredit() && queue->dispatch(shared_from_this());
- } catch (const SessionException& e) {
- throw SessionOutputException(e, parent->session.getChannel());
- }
-}
-
-void SemanticState::ConsumerImpl::enableNotify()
-{
- Mutex::ScopedLock l(lock);
- assertClusterSafe();
- notifyEnabled = true;
-}
-
-void SemanticState::ConsumerImpl::disableNotify()
-{
- Mutex::ScopedLock l(lock);
- notifyEnabled = false;
-}
-
-bool SemanticState::ConsumerImpl::isNotifyEnabled() const {
- Mutex::ScopedLock l(lock);
- return notifyEnabled;
-}
-
-void SemanticState::ConsumerImpl::notify()
-{
- Mutex::ScopedLock l(lock);
- assertClusterSafe();
- if (notifyEnabled) {
- parent->session.getConnection().outputTasks.addOutputTask(this);
- parent->session.getConnection().outputTasks.activateOutput();
- }
-}
-
-
-// Test that a DeliveryRecord's ID is in a sequence set and some other
-// predicate on DeliveryRecord holds.
-template <class Predicate> struct IsInSequenceSetAnd {
- IsInSequenceSet isInSet;
- Predicate predicate;
- IsInSequenceSetAnd(const SequenceSet& s, Predicate p) : isInSet(s), predicate(p) {}
- bool operator()(DeliveryRecord& dr) {
- return isInSet(dr.getId()) && predicate(dr);
- }
-};
-
-template<class Predicate> IsInSequenceSetAnd<Predicate>
-isInSequenceSetAnd(const SequenceSet& s, Predicate p) {
- return IsInSequenceSetAnd<Predicate>(s,p);
-}
-
-void SemanticState::accepted(const SequenceSet& commands) {
- assertClusterSafe();
- if (txBuffer.get()) {
- //in transactional mode, don't dequeue or remove, just
- //maintain set of acknowledged messages:
- accumulatedAck.add(commands);
-
- if (dtxBuffer.get()) {
- //if enlisted in a dtx, copy the relevant slice from
- //unacked and record it against that transaction
- TxOp::shared_ptr txAck(new DtxAck(accumulatedAck, unacked));
- accumulatedAck.clear();
- dtxBuffer->enlist(txAck);
-
- //mark the relevant messages as 'ended' in unacked
- //if the messages are already completed, they can be
- //removed from the record
- DeliveryRecords::iterator removed =
- remove_if(unacked.begin(), unacked.end(),
- isInSequenceSetAnd(commands,
- bind(&DeliveryRecord::setEnded, _1)));
- unacked.erase(removed, unacked.end());
- }
- } else {
- DeliveryRecords::iterator removed =
- remove_if(unacked.begin(), unacked.end(),
- isInSequenceSetAnd(commands,
- bind(&DeliveryRecord::accept, _1,
- (TransactionContext*) 0)));
- unacked.erase(removed, unacked.end());
- }
-}
-
-void SemanticState::completed(const SequenceSet& commands) {
- DeliveryRecords::iterator removed =
- remove_if(unacked.begin(), unacked.end(),
- isInSequenceSetAnd(commands,
- bind(&SemanticState::complete, this, _1)));
- unacked.erase(removed, unacked.end());
- requestDispatch();
-}
-
-void SemanticState::attached()
-{
- for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
- i->second->enableNotify();
- session.getConnection().outputTasks.addOutputTask(i->second.get());
- }
- session.getConnection().outputTasks.activateOutput();
-}
-
-void SemanticState::detached()
-{
- for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
- i->second->disableNotify();
- session.getConnection().outputTasks.removeOutputTask(i->second.get());
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SemanticState.h b/cpp/src/qpid/broker/SemanticState.h
deleted file mode 100644
index 8c69d6b89b..0000000000
--- a/cpp/src/qpid/broker/SemanticState.h
+++ /dev/null
@@ -1,257 +0,0 @@
-#ifndef QPID_BROKER_SEMANTICSTATE_H
-#define QPID_BROKER_SEMANTICSTATE_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/Consumer.h"
-#include "qpid/broker/Deliverable.h"
-#include "qpid/broker/DeliveryAdapter.h"
-#include "qpid/broker/DeliveryRecord.h"
-#include "qpid/broker/DtxBuffer.h"
-#include "qpid/broker/DtxManager.h"
-#include "qpid/broker/NameGenerator.h"
-#include "qpid/broker/TxBuffer.h"
-
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/framing/Uuid.h"
-#include "qpid/sys/AggregateOutput.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/AtomicValue.h"
-#include "qpid/broker/AclModule.h"
-#include "qmf/org/apache/qpid/broker/Subscription.h"
-
-#include <list>
-#include <map>
-#include <vector>
-
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/cast.hpp>
-
-namespace qpid {
-namespace broker {
-
-class SessionContext;
-
-/**
- *
- * SemanticState implements the behavior of a Session, especially the
- * state of consumers subscribed to queues. The code for ConsumerImpl
- * is also in SemanticState.cpp
- *
- * SemanticState holds the AMQP Execution and Model state of an open
- * session, whether attached to a channel or suspended. It is not
- * dependent on any specific AMQP version.
- *
- * Message delivery is driven by ConsumerImpl::doOutput(), which is
- * called when a client's socket is ready to write data.
- *
- */
-class SemanticState : private boost::noncopyable {
- public:
- class ConsumerImpl : public Consumer, public sys::OutputTask,
- public boost::enable_shared_from_this<ConsumerImpl>,
- public management::Manageable
- {
- mutable qpid::sys::Mutex lock;
- SemanticState* const parent;
- const std::string name;
- const boost::shared_ptr<Queue> queue;
- const bool ackExpected;
- const bool acquire;
- bool blocked;
- bool windowing;
- bool exclusive;
- std::string resumeId;
- uint64_t resumeTtl;
- framing::FieldTable arguments;
- uint32_t msgCredit;
- uint32_t byteCredit;
- bool notifyEnabled;
- const int syncFrequency;
- int deliveryCount;
- qmf::org::apache::qpid::broker::Subscription* mgmtObject;
-
- bool checkCredit(boost::intrusive_ptr<Message>& msg);
- void allocateCredit(boost::intrusive_ptr<Message>& msg);
- bool haveCredit();
-
- public:
- typedef boost::shared_ptr<ConsumerImpl> shared_ptr;
-
- ConsumerImpl(SemanticState* parent,
- const std::string& name, boost::shared_ptr<Queue> queue,
- bool ack, bool acquire, bool exclusive,
- const std::string& resumeId, uint64_t resumeTtl, const framing::FieldTable& arguments);
- ~ConsumerImpl();
- OwnershipToken* getSession();
- bool deliver(QueuedMessage& msg);
- bool filter(boost::intrusive_ptr<Message> msg);
- bool accept(boost::intrusive_ptr<Message> msg);
-
- void disableNotify();
- void enableNotify();
- void notify();
- bool isNotifyEnabled() const;
-
- void requestDispatch();
-
- void setWindowMode();
- void setCreditMode();
- void addByteCredit(uint32_t value);
- void addMessageCredit(uint32_t value);
- void flush();
- void stop();
- void complete(DeliveryRecord&);
- boost::shared_ptr<Queue> getQueue() const { return queue; }
- bool isBlocked() const { return blocked; }
- bool setBlocked(bool set) { std::swap(set, blocked); return set; }
-
- bool doOutput();
-
- std::string getName() const { return name; }
-
- bool isAckExpected() const { return ackExpected; }
- bool isAcquire() const { return acquire; }
- bool isWindowing() const { return windowing; }
- bool isExclusive() const { return exclusive; }
- uint32_t getMsgCredit() const { return msgCredit; }
- uint32_t getByteCredit() const { return byteCredit; }
- std::string getResumeId() const { return resumeId; };
- uint64_t getResumeTtl() const { return resumeTtl; }
- const framing::FieldTable& getArguments() const { return arguments; }
-
- SemanticState& getParent() { return *parent; }
- const SemanticState& getParent() const { return *parent; }
- // Manageable entry points
- management::ManagementObject* GetManagementObject (void) const;
- management::Manageable::status_t ManagementMethod (uint32_t methodId, management::Args& args, std::string& text);
- };
-
- private:
- typedef std::map<std::string, ConsumerImpl::shared_ptr> ConsumerImplMap;
- typedef std::map<std::string, DtxBuffer::shared_ptr> DtxBufferMap;
-
- SessionContext& session;
- DeliveryAdapter& deliveryAdapter;
- ConsumerImplMap consumers;
- NameGenerator tagGenerator;
- DeliveryRecords unacked;
- TxBuffer::shared_ptr txBuffer;
- DtxBuffer::shared_ptr dtxBuffer;
- bool dtxSelected;
- DtxBufferMap suspendedXids;
- framing::SequenceSet accumulatedAck;
- boost::shared_ptr<Exchange> cacheExchange;
- AclModule* acl;
- const bool authMsg;
- const std::string userID;
- const std::string userName;
- const bool isDefaultRealm;
- bool closeComplete;
-
- void route(boost::intrusive_ptr<Message> msg, Deliverable& strategy);
- void checkDtxTimeout();
-
- bool complete(DeliveryRecord&);
- AckRange findRange(DeliveryId first, DeliveryId last);
- void requestDispatch();
- void cancel(ConsumerImpl::shared_ptr);
- void unsubscribe(ConsumerImpl::shared_ptr);
- void disable(ConsumerImpl::shared_ptr);
-
- public:
- SemanticState(DeliveryAdapter&, SessionContext&);
- ~SemanticState();
-
- SessionContext& getSession() { return session; }
- const SessionContext& getSession() const { return session; }
-
- ConsumerImpl& find(const std::string& destination);
-
- /**
- * Get named queue, never returns 0.
- * @return: named queue
- * @exception: ChannelException if no queue of that name is found.
- * @exception: ConnectionException if name="" and session has no default.
- */
- boost::shared_ptr<Queue> getQueue(const std::string& name) const;
-
- bool exists(const std::string& consumerTag);
-
- void consume(const std::string& destination,
- boost::shared_ptr<Queue> queue,
- bool ackRequired, bool acquire, bool exclusive,
- const std::string& resumeId=std::string(), uint64_t resumeTtl=0,
- const framing::FieldTable& = framing::FieldTable());
-
- bool cancel(const std::string& tag);
-
- void setWindowMode(const std::string& destination);
- void setCreditMode(const std::string& destination);
- void addByteCredit(const std::string& destination, uint32_t value);
- void addMessageCredit(const std::string& destination, uint32_t value);
- void flush(const std::string& destination);
- void stop(const std::string& destination);
-
- void startTx();
- void commit(MessageStore* const store);
- void rollback();
- void selectDtx();
- void startDtx(const std::string& xid, DtxManager& mgr, bool join);
- void endDtx(const std::string& xid, bool fail);
- void suspendDtx(const std::string& xid);
- void resumeDtx(const std::string& xid);
- void recover(bool requeue);
- void deliver(DeliveryRecord& message, bool sync);
- void acquire(DeliveryId first, DeliveryId last, DeliveryIds& acquired);
- void release(DeliveryId first, DeliveryId last, bool setRedelivered);
- void reject(DeliveryId first, DeliveryId last);
- void handle(boost::intrusive_ptr<Message> msg);
-
- void completed(const framing::SequenceSet& commands);
- void accepted(const framing::SequenceSet& commands);
-
- void attached();
- void detached();
- void closed();
-
- // Used by cluster to re-create sessions
- template <class F> void eachConsumer(F f) {
- for(ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); ++i)
- f(i->second);
- }
- DeliveryRecords& getUnacked() { return unacked; }
- framing::SequenceSet getAccumulatedAck() const { return accumulatedAck; }
- TxBuffer::shared_ptr getTxBuffer() const { return txBuffer; }
- void setTxBuffer(const TxBuffer::shared_ptr& txb) { txBuffer = txb; }
- void setAccumulatedAck(const framing::SequenceSet& s) { accumulatedAck = s; }
- void record(const DeliveryRecord& delivery);
-};
-
-}} // namespace qpid::broker
-
-
-
-
-#endif /*!QPID_BROKER_SEMANTICSTATE_H*/
diff --git a/cpp/src/qpid/broker/SessionAdapter.cpp b/cpp/src/qpid/broker/SessionAdapter.cpp
deleted file mode 100644
index 63c4b660b2..0000000000
--- a/cpp/src/qpid/broker/SessionAdapter.cpp
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-#include "qpid/broker/SessionAdapter.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/Exception.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/framing/enum.h"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/broker/SessionState.h"
-#include "qmf/org/apache/qpid/broker/EventExchangeDeclare.h"
-#include "qmf/org/apache/qpid/broker/EventExchangeDelete.h"
-#include "qmf/org/apache/qpid/broker/EventQueueDeclare.h"
-#include "qmf/org/apache/qpid/broker/EventQueueDelete.h"
-#include "qmf/org/apache/qpid/broker/EventBind.h"
-#include "qmf/org/apache/qpid/broker/EventUnbind.h"
-#include "qmf/org/apache/qpid/broker/EventSubscribe.h"
-#include "qmf/org/apache/qpid/broker/EventUnsubscribe.h"
-#include <boost/format.hpp>
-#include <boost/cast.hpp>
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace broker {
-
-using namespace qpid;
-using namespace qpid::framing;
-using namespace qpid::framing::dtx;
-using namespace qpid::management;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-typedef std::vector<Queue::shared_ptr> QueueVector;
-
-SessionAdapter::SessionAdapter(SemanticState& s) :
- HandlerImpl(s),
- exchangeImpl(s),
- queueImpl(s),
- messageImpl(s),
- executionImpl(s),
- txImpl(s),
- dtxImpl(s)
-{}
-
-static const std::string _TRUE("true");
-static const std::string _FALSE("false");
-
-void SessionAdapter::ExchangeHandlerImpl::declare(const string& exchange, const string& type,
- const string& alternateExchange,
- bool passive, bool durable, bool /*autoDelete*/, const FieldTable& args){
-
- //TODO: implement autoDelete
- Exchange::shared_ptr alternate;
- if (!alternateExchange.empty()) {
- alternate = getBroker().getExchanges().get(alternateExchange);
- }
- if(passive){
- AclModule* acl = getBroker().getAcl();
- if (acl) {
- //TODO: why does a passive declare require create
- //permission? The purpose of the passive flag is to state
- //that the exchange should *not* created. For
- //authorisation a passive declare is similar to
- //exchange-query.
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_TYPE, type));
- params.insert(make_pair(acl::PROP_ALTERNATE, alternateExchange));
- params.insert(make_pair(acl::PROP_PASSIVE, _TRUE));
- params.insert(make_pair(acl::PROP_DURABLE, durable ? _TRUE : _FALSE));
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_CREATE,acl::OBJ_EXCHANGE,exchange,&params) )
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied exchange create request from " << getConnection().getUserId()));
- }
- Exchange::shared_ptr actual(getBroker().getExchanges().get(exchange));
- checkType(actual, type);
- checkAlternate(actual, alternate);
- }else{
- if(exchange.find("amq.") == 0 || exchange.find("qpid.") == 0) {
- throw framing::NotAllowedException(QPID_MSG("Exchange names beginning with \"amq.\" or \"qpid.\" are reserved. (exchange=\"" << exchange << "\")"));
- }
- try{
- std::pair<Exchange::shared_ptr, bool> response =
- getBroker().createExchange(exchange, type, durable, alternateExchange, args,
- getConnection().getUserId(), getConnection().getUrl());
- if (!response.second) {
- //exchange already there, not created
- checkType(response.first, type);
- checkAlternate(response.first, alternate);
- ManagementAgent* agent = getBroker().getManagementAgent();
- if (agent)
- agent->raiseEvent(_qmf::EventExchangeDeclare(getConnection().getUrl(),
- getConnection().getUserId(),
- exchange,
- type,
- alternateExchange,
- durable,
- false,
- ManagementAgent::toMap(args),
- "existing"));
- }
- }catch(UnknownExchangeTypeException& /*e*/){
- throw NotFoundException(QPID_MSG("Exchange type not implemented: " << type));
- }
- }
-}
-
-void SessionAdapter::ExchangeHandlerImpl::checkType(Exchange::shared_ptr exchange, const std::string& type)
-{
- if (!type.empty() && exchange->getType() != type) {
- throw NotAllowedException(QPID_MSG("Exchange declared to be of type " << exchange->getType() << ", requested " << type));
- }
-}
-
-void SessionAdapter::ExchangeHandlerImpl::checkAlternate(Exchange::shared_ptr exchange, Exchange::shared_ptr alternate)
-{
- if (alternate && ((exchange->getAlternate() && alternate != exchange->getAlternate())
- || !exchange->getAlternate()))
- throw NotAllowedException(QPID_MSG("Exchange declared with alternate-exchange "
- << (exchange->getAlternate() ? exchange->getAlternate()->getName() : "<nonexistent>")
- << ", requested "
- << alternate->getName()));
-}
-
-void SessionAdapter::ExchangeHandlerImpl::delete_(const string& name, bool /*ifUnused*/)
-{
- //TODO: implement if-unused
- getBroker().deleteExchange(name, getConnection().getUserId(), getConnection().getUrl());
-}
-
-ExchangeQueryResult SessionAdapter::ExchangeHandlerImpl::query(const string& name)
-{
- AclModule* acl = getBroker().getAcl();
- if (acl) {
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_ACCESS,acl::OBJ_EXCHANGE,name,NULL) )
- throw UnauthorizedAccessException(QPID_MSG("ACL denied exchange query request from " << getConnection().getUserId()));
- }
-
- try {
- Exchange::shared_ptr exchange(getBroker().getExchanges().get(name));
- return ExchangeQueryResult(exchange->getType(), exchange->isDurable(), false, exchange->getArgs());
- } catch (const NotFoundException& /*e*/) {
- return ExchangeQueryResult("", false, true, FieldTable());
- }
-}
-
-void SessionAdapter::ExchangeHandlerImpl::bind(const string& queueName,
- const string& exchangeName, const string& routingKey,
- const FieldTable& arguments)
-{
- getBroker().bind(queueName, exchangeName, routingKey, arguments,
- getConnection().getUserId(), getConnection().getUrl());
-}
-
-void SessionAdapter::ExchangeHandlerImpl::unbind(const string& queueName,
- const string& exchangeName,
- const string& routingKey)
-{
- getBroker().unbind(queueName, exchangeName, routingKey,
- getConnection().getUserId(), getConnection().getUrl());
-}
-
-ExchangeBoundResult SessionAdapter::ExchangeHandlerImpl::bound(const std::string& exchangeName,
- const std::string& queueName,
- const std::string& key,
- const framing::FieldTable& args)
-{
- AclModule* acl = getBroker().getAcl();
- if (acl) {
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_QUEUENAME, queueName));
- params.insert(make_pair(acl::PROP_ROUTINGKEY, key));
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_ACCESS,acl::OBJ_EXCHANGE,exchangeName,&params) )
- throw UnauthorizedAccessException(QPID_MSG("ACL denied exchange bound request from " << getConnection().getUserId()));
- }
-
- Exchange::shared_ptr exchange;
- try {
- exchange = getBroker().getExchanges().get(exchangeName);
- } catch (const NotFoundException&) {}
-
- Queue::shared_ptr queue;
- if (!queueName.empty()) {
- queue = getBroker().getQueues().find(queueName);
- }
-
- if (!exchange) {
- return ExchangeBoundResult(true, (!queueName.empty() && !queue), false, false, false);
- } else if (!queueName.empty() && !queue) {
- return ExchangeBoundResult(false, true, false, false, false);
- } else if (exchange->isBound(queue, key.empty() ? 0 : &key, args.count() > 0 ? &args : &args)) {
- return ExchangeBoundResult(false, false, false, false, false);
- } else {
- //need to test each specified option individually
- bool queueMatched = queueName.empty() || exchange->isBound(queue, 0, 0);
- bool keyMatched = key.empty() || exchange->isBound(Queue::shared_ptr(), &key, 0);
- bool argsMatched = args.count() == 0 || exchange->isBound(Queue::shared_ptr(), 0, &args);
-
- return ExchangeBoundResult(false, false, !queueMatched, !keyMatched, !argsMatched);
- }
-}
-
-SessionAdapter::QueueHandlerImpl::QueueHandlerImpl(SemanticState& session) : HandlerHelper(session), broker(getBroker())
-{}
-
-
-SessionAdapter::QueueHandlerImpl::~QueueHandlerImpl()
-{
- try {
- destroyExclusiveQueues();
- } catch (std::exception& e) {
- QPID_LOG(error, e.what());
- }
-}
-
-void SessionAdapter::QueueHandlerImpl::destroyExclusiveQueues()
-{
- while (!exclusiveQueues.empty()) {
- Queue::shared_ptr q(exclusiveQueues.front());
- q->releaseExclusiveOwnership();
- if (q->canAutoDelete()) {
- Queue::tryAutoDelete(broker, q);
- }
- exclusiveQueues.erase(exclusiveQueues.begin());
- }
-}
-
-bool SessionAdapter::QueueHandlerImpl::isLocal(const ConnectionToken* t) const
-{
- return session.isLocal(t);
-}
-
-
-QueueQueryResult SessionAdapter::QueueHandlerImpl::query(const string& name)
-{
- AclModule* acl = getBroker().getAcl();
- if (acl) {
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_ACCESS,acl::OBJ_QUEUE,name,NULL) )
- throw UnauthorizedAccessException(QPID_MSG("ACL denied queue query request from " << getConnection().getUserId()));
- }
-
- Queue::shared_ptr queue = session.getBroker().getQueues().find(name);
- if (queue) {
-
- Exchange::shared_ptr alternateExchange = queue->getAlternateExchange();
-
- return QueueQueryResult(queue->getName(),
- alternateExchange ? alternateExchange->getName() : "",
- queue->isDurable(),
- queue->hasExclusiveOwner(),
- queue->isAutoDelete(),
- queue->getSettings(),
- queue->getMessageCount(),
- queue->getConsumerCount());
- } else {
- return QueueQueryResult();
- }
-}
-
-void SessionAdapter::QueueHandlerImpl::declare(const string& name, const string& alternateExchange,
- bool passive, bool durable, bool exclusive,
- bool autoDelete, const qpid::framing::FieldTable& arguments)
-{
- Queue::shared_ptr queue;
- if (passive && !name.empty()) {
- AclModule* acl = getBroker().getAcl();
- if (acl) {
- //TODO: why does a passive declare require create
- //permission? The purpose of the passive flag is to state
- //that the queue should *not* created. For
- //authorisation a passive declare is similar to
- //queue-query (or indeed a qmf query).
- std::map<acl::Property, std::string> params;
- params.insert(make_pair(acl::PROP_ALTERNATE, alternateExchange));
- params.insert(make_pair(acl::PROP_PASSIVE, _TRUE));
- params.insert(make_pair(acl::PROP_DURABLE, std::string(durable ? _TRUE : _FALSE)));
- params.insert(make_pair(acl::PROP_EXCLUSIVE, std::string(exclusive ? _TRUE : _FALSE)));
- params.insert(make_pair(acl::PROP_AUTODELETE, std::string(autoDelete ? _TRUE : _FALSE)));
- params.insert(make_pair(acl::PROP_POLICYTYPE, arguments.getAsString("qpid.policy_type")));
- params.insert(make_pair(acl::PROP_MAXQUEUECOUNT, boost::lexical_cast<string>(arguments.getAsInt("qpid.max_count"))));
- params.insert(make_pair(acl::PROP_MAXQUEUESIZE, boost::lexical_cast<string>(arguments.getAsInt64("qpid.max_size"))));
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_CREATE,acl::OBJ_QUEUE,name,&params) )
- throw UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << getConnection().getUserId()));
- }
- queue = getQueue(name);
- //TODO: check alternate-exchange is as expected
- } else {
- std::pair<Queue::shared_ptr, bool> queue_created =
- getBroker().createQueue(name, durable,
- autoDelete,
- exclusive ? &session : 0,
- alternateExchange,
- arguments,
- getConnection().getUserId(),
- getConnection().getUrl());
- queue = queue_created.first;
- assert(queue);
- if (queue_created.second) { // This is a new queue
- //handle automatic cleanup:
- if (exclusive) {
- exclusiveQueues.push_back(queue);
- }
- } else {
- if (exclusive && queue->setExclusiveOwner(&session)) {
- exclusiveQueues.push_back(queue);
- }
- ManagementAgent* agent = getBroker().getManagementAgent();
- if (agent)
- agent->raiseEvent(_qmf::EventQueueDeclare(getConnection().getUrl(), getConnection().getUserId(),
- name, durable, exclusive, autoDelete, ManagementAgent::toMap(arguments),
- "existing"));
- }
-
- }
-
- if (exclusive && !queue->isExclusiveOwner(&session))
- throw ResourceLockedException(QPID_MSG("Cannot grant exclusive access to queue "
- << queue->getName()));
-}
-
-void SessionAdapter::QueueHandlerImpl::purge(const string& queue){
- AclModule* acl = getBroker().getAcl();
- if (acl)
- {
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_PURGE,acl::OBJ_QUEUE,queue,NULL) )
- throw UnauthorizedAccessException(QPID_MSG("ACL denied queue purge request from " << getConnection().getUserId()));
- }
- getQueue(queue)->purge();
-}
-
-void SessionAdapter::QueueHandlerImpl::checkDelete(Queue::shared_ptr queue, bool ifUnused, bool ifEmpty)
-{
- if (queue->hasExclusiveOwner() && !queue->isExclusiveOwner(&session)) {
- throw ResourceLockedException(QPID_MSG("Cannot delete queue "
- << queue->getName() << "; it is exclusive to another session"));
- } else if(ifEmpty && queue->getMessageCount() > 0) {
- throw PreconditionFailedException(QPID_MSG("Cannot delete queue "
- << queue->getName() << "; queue not empty"));
- } else if(ifUnused && queue->getConsumerCount() > 0) {
- throw PreconditionFailedException(QPID_MSG("Cannot delete queue "
- << queue->getName() << "; queue in use"));
- } else if (queue->isExclusiveOwner(&session)) {
- //remove the queue from the list of exclusive queues if necessary
- QueueVector::iterator i = std::find(exclusiveQueues.begin(),
- exclusiveQueues.end(),
- queue);
- if (i < exclusiveQueues.end()) exclusiveQueues.erase(i);
- }
-}
-
-void SessionAdapter::QueueHandlerImpl::delete_(const string& queue, bool ifUnused, bool ifEmpty)
-{
- getBroker().deleteQueue(queue, getConnection().getUserId(), getConnection().getUrl(),
- boost::bind(&SessionAdapter::QueueHandlerImpl::checkDelete, this, _1, ifUnused, ifEmpty));
-}
-
-SessionAdapter::MessageHandlerImpl::MessageHandlerImpl(SemanticState& s) :
- HandlerHelper(s),
- releaseRedeliveredOp(boost::bind(&SemanticState::release, &state, _1, _2, true)),
- releaseOp(boost::bind(&SemanticState::release, &state, _1, _2, false)),
- rejectOp(boost::bind(&SemanticState::reject, &state, _1, _2))
- {}
-
-//
-// Message class method handlers
-//
-
-void SessionAdapter::MessageHandlerImpl::transfer(const string& /*destination*/,
- uint8_t /*acceptMode*/,
- uint8_t /*acquireMode*/)
-{
- //not yet used (content containing assemblies treated differently at present
- std::cout << "SessionAdapter::MessageHandlerImpl::transfer() called" << std::endl;
-}
-
-void SessionAdapter::MessageHandlerImpl::release(const SequenceSet& transfers, bool setRedelivered)
-{
- transfers.for_each(setRedelivered ? releaseRedeliveredOp : releaseOp);
-}
-
-void
-SessionAdapter::MessageHandlerImpl::subscribe(const string& queueName,
- const string& destination,
- uint8_t acceptMode,
- uint8_t acquireMode,
- bool exclusive,
- const string& resumeId,
- uint64_t resumeTtl,
- const FieldTable& arguments)
-{
-
- AclModule* acl = getBroker().getAcl();
- if (acl)
- {
- if (!acl->authorise(getConnection().getUserId(),acl::ACT_CONSUME,acl::OBJ_QUEUE,queueName,NULL) )
- throw UnauthorizedAccessException(QPID_MSG("ACL denied Queue subscribe request from " << getConnection().getUserId()));
- }
-
- Queue::shared_ptr queue = getQueue(queueName);
- if(!destination.empty() && state.exists(destination))
- throw NotAllowedException(QPID_MSG("Consumer tags must be unique"));
-
- if (queue->hasExclusiveOwner() && !queue->isExclusiveOwner(&session) && acquireMode == 0)
- throw ResourceLockedException(QPID_MSG("Cannot subscribe to exclusive queue "
- << queue->getName()));
-
- state.consume(destination, queue,
- acceptMode == 0, acquireMode == 0, exclusive,
- resumeId, resumeTtl, arguments);
-
- ManagementAgent* agent = getBroker().getManagementAgent();
- if (agent)
- agent->raiseEvent(_qmf::EventSubscribe(getConnection().getUrl(), getConnection().getUserId(),
- queueName, destination, exclusive, ManagementAgent::toMap(arguments)));
-}
-
-void
-SessionAdapter::MessageHandlerImpl::cancel(const string& destination )
-{
- if (!state.cancel(destination)) {
- throw NotFoundException(QPID_MSG("No such subscription: " << destination));
- }
-
- ManagementAgent* agent = getBroker().getManagementAgent();
- if (agent)
- agent->raiseEvent(_qmf::EventUnsubscribe(getConnection().getUrl(), getConnection().getUserId(), destination));
-}
-
-void
-SessionAdapter::MessageHandlerImpl::reject(const SequenceSet& transfers, uint16_t /*code*/, const string& /*text*/ )
-{
- transfers.for_each(rejectOp);
-}
-
-void SessionAdapter::MessageHandlerImpl::flow(const std::string& destination, uint8_t unit, uint32_t value)
-{
- if (unit == 0) {
- //message
- state.addMessageCredit(destination, value);
- } else if (unit == 1) {
- //bytes
- state.addByteCredit(destination, value);
- } else {
- //unknown
- throw InvalidArgumentException(QPID_MSG("Invalid value for unit " << unit));
- }
-
-}
-
-void SessionAdapter::MessageHandlerImpl::setFlowMode(const std::string& destination, uint8_t mode)
-{
- if (mode == 0) {
- //credit
- state.setCreditMode(destination);
- } else if (mode == 1) {
- //window
- state.setWindowMode(destination);
- } else{
- throw InvalidArgumentException(QPID_MSG("Invalid value for mode " << mode));
- }
-}
-
-void SessionAdapter::MessageHandlerImpl::flush(const std::string& destination)
-{
- state.flush(destination);
-}
-
-void SessionAdapter::MessageHandlerImpl::stop(const std::string& destination)
-{
- state.stop(destination);
-}
-
-void SessionAdapter::MessageHandlerImpl::accept(const framing::SequenceSet& commands)
-{
- state.accepted(commands);
-}
-
-framing::MessageAcquireResult SessionAdapter::MessageHandlerImpl::acquire(const framing::SequenceSet& transfers)
-{
- // FIXME aconway 2008-05-12: create SequenceSet directly, no need for intermediate results vector.
- SequenceNumberSet results;
- RangedOperation f = boost::bind(&SemanticState::acquire, &state, _1, _2, boost::ref(results));
- transfers.for_each(f);
-
- results = results.condense();
- SequenceSet acquisitions;
- RangedOperation g = boost::bind(&SequenceSet::add, &acquisitions, _1, _2);
- results.processRanges(g);
-
- return MessageAcquireResult(acquisitions);
-}
-
-framing::MessageResumeResult SessionAdapter::MessageHandlerImpl::resume(const std::string& /*destination*/,
- const std::string& /*resumeId*/)
-{
- throw NotImplementedException("resuming transfers not yet supported");
-}
-
-
-
-void SessionAdapter::ExecutionHandlerImpl::sync()
-{
- session.addPendingExecutionSync();
- /** @todo KAG - need a generic mechanism to allow a command to returning "not completed" status back to SessionState */
-
-}
-
-void SessionAdapter::ExecutionHandlerImpl::result(const SequenceNumber& /*commandId*/, const string& /*value*/)
-{
- //TODO: but currently never used client->server
-}
-
-void SessionAdapter::ExecutionHandlerImpl::exception(uint16_t /*errorCode*/,
- const SequenceNumber& /*commandId*/,
- uint8_t /*classCode*/,
- uint8_t /*commandCode*/,
- uint8_t /*fieldIndex*/,
- const std::string& /*description*/,
- const framing::FieldTable& /*errorInfo*/)
-{
- //TODO: again, not really used client->server but may be important
- //for inter-broker links
-}
-
-
-
-void SessionAdapter::TxHandlerImpl::select()
-{
- state.startTx();
-}
-
-void SessionAdapter::TxHandlerImpl::commit()
-{
- state.commit(&getBroker().getStore());
-}
-
-void SessionAdapter::TxHandlerImpl::rollback()
-{
- state.rollback();
-}
-
-std::string SessionAdapter::DtxHandlerImpl::convert(const framing::Xid& xid)
-{
- std::string encoded;
- encode(xid, encoded);
- return encoded;
-}
-
-void SessionAdapter::DtxHandlerImpl::select()
-{
- state.selectDtx();
-}
-
-XaResult SessionAdapter::DtxHandlerImpl::end(const Xid& xid,
- bool fail,
- bool suspend)
-{
- try {
- if (fail) {
- state.endDtx(convert(xid), true);
- if (suspend) {
- throw CommandInvalidException(QPID_MSG("End and suspend cannot both be set."));
- } else {
- return XaResult(XA_STATUS_XA_RBROLLBACK);
- }
- } else {
- if (suspend) {
- state.suspendDtx(convert(xid));
- } else {
- state.endDtx(convert(xid), false);
- }
- return XaResult(XA_STATUS_XA_OK);
- }
- } catch (const DtxTimeoutException& /*e*/) {
- return XaResult(XA_STATUS_XA_RBTIMEOUT);
- }
-}
-
-XaResult SessionAdapter::DtxHandlerImpl::start(const Xid& xid,
- bool join,
- bool resume)
-{
- if (join && resume) {
- throw CommandInvalidException(QPID_MSG("Join and resume cannot both be set."));
- }
- try {
- if (resume) {
- state.resumeDtx(convert(xid));
- } else {
- state.startDtx(convert(xid), getBroker().getDtxManager(), join);
- }
- return XaResult(XA_STATUS_XA_OK);
- } catch (const DtxTimeoutException& /*e*/) {
- return XaResult(XA_STATUS_XA_RBTIMEOUT);
- }
-}
-
-XaResult SessionAdapter::DtxHandlerImpl::prepare(const Xid& xid)
-{
- try {
- bool ok = getBroker().getDtxManager().prepare(convert(xid));
- return XaResult(ok ? XA_STATUS_XA_OK : XA_STATUS_XA_RBROLLBACK);
- } catch (const DtxTimeoutException& /*e*/) {
- return XaResult(XA_STATUS_XA_RBTIMEOUT);
- }
-}
-
-XaResult SessionAdapter::DtxHandlerImpl::commit(const Xid& xid,
- bool onePhase)
-{
- try {
- bool ok = getBroker().getDtxManager().commit(convert(xid), onePhase);
- return XaResult(ok ? XA_STATUS_XA_OK : XA_STATUS_XA_RBROLLBACK);
- } catch (const DtxTimeoutException& /*e*/) {
- return XaResult(XA_STATUS_XA_RBTIMEOUT);
- }
-}
-
-
-XaResult SessionAdapter::DtxHandlerImpl::rollback(const Xid& xid)
-{
- try {
- getBroker().getDtxManager().rollback(convert(xid));
- return XaResult(XA_STATUS_XA_OK);
- } catch (const DtxTimeoutException& /*e*/) {
- return XaResult(XA_STATUS_XA_RBTIMEOUT);
- }
-}
-
-DtxRecoverResult SessionAdapter::DtxHandlerImpl::recover()
-{
- std::set<std::string> xids;
- getBroker().getStore().collectPreparedXids(xids);
- /*
- * create array of long structs
- */
- Array indoubt(0xAB);
- for (std::set<std::string>::iterator i = xids.begin(); i != xids.end(); i++) {
- boost::shared_ptr<FieldValue> xid(new Struct32Value(*i));
- indoubt.add(xid);
- }
- return DtxRecoverResult(indoubt);
-}
-
-void SessionAdapter::DtxHandlerImpl::forget(const Xid& xid)
-{
- //Currently no heuristic completion is supported, so this should never be used.
- throw NotImplementedException(QPID_MSG("Forget not implemented. Branch with xid " << xid << " not heuristically completed!"));
-}
-
-DtxGetTimeoutResult SessionAdapter::DtxHandlerImpl::getTimeout(const Xid& xid)
-{
- uint32_t timeout = getBroker().getDtxManager().getTimeout(convert(xid));
- return DtxGetTimeoutResult(timeout);
-}
-
-
-void SessionAdapter::DtxHandlerImpl::setTimeout(const Xid& xid,
- uint32_t timeout)
-{
- getBroker().getDtxManager().setTimeout(convert(xid), timeout);
-}
-
-
-Queue::shared_ptr SessionAdapter::HandlerHelper::getQueue(const string& name) const {
- Queue::shared_ptr queue;
- if (name.empty()) {
- throw framing::IllegalArgumentException(QPID_MSG("No queue name specified."));
- } else {
- queue = session.getBroker().getQueues().find(name);
- if (!queue)
- throw framing::NotFoundException(QPID_MSG("Queue not found: "<<name));
- }
- return queue;
-}
-
-}} // namespace qpid::broker
-
-
diff --git a/cpp/src/qpid/broker/SessionAdapter.h b/cpp/src/qpid/broker/SessionAdapter.h
deleted file mode 100644
index 8987c4812f..0000000000
--- a/cpp/src/qpid/broker/SessionAdapter.h
+++ /dev/null
@@ -1,273 +0,0 @@
-#ifndef _broker_SessionAdapter_h
-#define _broker_SessionAdapter_h
-
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "qpid/broker/HandlerImpl.h"
-
-#include "qpid/broker/ConnectionToken.h"
-#include "qpid/broker/OwnershipToken.h"
-#include "qpid/Exception.h"
-#include "qpid/framing/AMQP_ServerOperations.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/framing/StructHelper.h"
-
-#include <algorithm>
-#include <vector>
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-class Channel;
-class Connection;
-class Broker;
-class Queue;
-
-/**
- * SessionAdapter translates protocol-specific AMQP commands for one
- * specific version of AMQP into calls on the core broker objects. It
- * is a container for a collection of adapters.
- *
- * Each adapter class provides a client proxy to send methods to the
- * peer broker or client.
- *
- */
-
- class SessionAdapter : public HandlerImpl, public framing::AMQP_ServerOperations
-{
- public:
- SessionAdapter(SemanticState& session);
-
- framing::ProtocolVersion getVersion() const { return session.getConnection().getVersion();}
-
- MessageHandler* getMessageHandler(){ return &messageImpl; }
- ExchangeHandler* getExchangeHandler(){ return &exchangeImpl; }
- QueueHandler* getQueueHandler(){ return &queueImpl; }
- ExecutionHandler* getExecutionHandler(){ return &executionImpl; }
- TxHandler* getTxHandler(){ return &txImpl; }
- DtxHandler* getDtxHandler(){ return &dtxImpl; }
-
- ConnectionHandler* getConnectionHandler() { throw framing::NotImplementedException("Class not implemented"); }
- SessionHandler* getSessionHandler() { throw framing::NotImplementedException("Class not implemented"); }
- FileHandler* getFileHandler() { throw framing::NotImplementedException("Class not implemented"); }
- StreamHandler* getStreamHandler() { throw framing::NotImplementedException("Class not implemented"); }
-
- template <class F> void eachExclusiveQueue(F f)
- {
- queueImpl.eachExclusiveQueue(f);
- }
-
-
- private:
- //common base for utility methods etc that are specific to this adapter
- struct HandlerHelper : public HandlerImpl
- {
- HandlerHelper(SemanticState& s) : HandlerImpl(s) {}
-
- boost::shared_ptr<Queue> getQueue(const std::string& name) const;
- };
-
-
- class ExchangeHandlerImpl :
- public ExchangeHandler,
- public HandlerHelper
- {
- public:
- ExchangeHandlerImpl(SemanticState& session) : HandlerHelper(session) {}
-
- void declare(const std::string& exchange, const std::string& type,
- const std::string& alternateExchange,
- bool passive, bool durable, bool autoDelete,
- const qpid::framing::FieldTable& arguments);
- void delete_(const std::string& exchange, bool ifUnused);
- framing::ExchangeQueryResult query(const std::string& name);
- void bind(const std::string& queue,
- const std::string& exchange, const std::string& routingKey,
- const qpid::framing::FieldTable& arguments);
- void unbind(const std::string& queue,
- const std::string& exchange,
- const std::string& routingKey);
- framing::ExchangeBoundResult bound(const std::string& exchange,
- const std::string& queue,
- const std::string& routingKey,
- const framing::FieldTable& arguments);
- private:
- void checkType(boost::shared_ptr<Exchange> exchange, const std::string& type);
-
- void checkAlternate(boost::shared_ptr<Exchange> exchange,
- boost::shared_ptr<Exchange> alternate);
- };
-
- class QueueHandlerImpl : public QueueHandler,
- public HandlerHelper
- {
- Broker& broker;
- std::vector< boost::shared_ptr<Queue> > exclusiveQueues;
-
- public:
- QueueHandlerImpl(SemanticState& session);
- ~QueueHandlerImpl();
-
- void declare(const std::string& queue,
- const std::string& alternateExchange,
- bool passive, bool durable, bool exclusive,
- bool autoDelete,
- const qpid::framing::FieldTable& arguments);
- void delete_(const std::string& queue,
- bool ifUnused, bool ifEmpty);
- void purge(const std::string& queue);
- framing::QueueQueryResult query(const std::string& queue);
- bool isLocal(const ConnectionToken* t) const;
-
- void destroyExclusiveQueues();
- void checkDelete(boost::shared_ptr<Queue> queue, bool ifUnused, bool ifEmpty);
- template <class F> void eachExclusiveQueue(F f)
- {
- std::for_each(exclusiveQueues.begin(), exclusiveQueues.end(), f);
- }
- };
-
- class MessageHandlerImpl :
- public MessageHandler,
- public HandlerHelper
- {
- typedef boost::function<void(DeliveryId, DeliveryId)> RangedOperation;
- RangedOperation releaseRedeliveredOp;
- RangedOperation releaseOp;
- RangedOperation rejectOp;
- RangedOperation acceptOp;
-
- public:
- MessageHandlerImpl(SemanticState& session);
- void transfer(const std::string& destination,
- uint8_t acceptMode,
- uint8_t acquireMode);
-
- void accept(const framing::SequenceSet& commands);
-
- void reject(const framing::SequenceSet& commands,
- uint16_t code,
- const std::string& text);
-
- void release(const framing::SequenceSet& commands,
- bool setRedelivered);
-
- framing::MessageAcquireResult acquire(const framing::SequenceSet&);
-
- void subscribe(const std::string& queue,
- const std::string& destination,
- uint8_t acceptMode,
- uint8_t acquireMode,
- bool exclusive,
- const std::string& resumeId,
- uint64_t resumeTtl,
- const framing::FieldTable& arguments);
-
- void cancel(const std::string& destination);
-
- void setFlowMode(const std::string& destination,
- uint8_t flowMode);
-
- void flow(const std::string& destination,
- uint8_t unit,
- uint32_t value);
-
- void flush(const std::string& destination);
-
- void stop(const std::string& destination);
-
- framing::MessageResumeResult resume(const std::string& destination,
- const std::string& resumeId);
-
- };
-
- class ExecutionHandlerImpl : public ExecutionHandler, public HandlerHelper
- {
- public:
- ExecutionHandlerImpl(SemanticState& session) : HandlerHelper(session) {}
-
- void sync();
- void result(const framing::SequenceNumber& commandId, const std::string& value);
- void exception(uint16_t errorCode,
- const framing::SequenceNumber& commandId,
- uint8_t classCode,
- uint8_t commandCode,
- uint8_t fieldIndex,
- const std::string& description,
- const framing::FieldTable& errorInfo);
-
- };
-
- class TxHandlerImpl : public TxHandler, public HandlerHelper
- {
- public:
- TxHandlerImpl(SemanticState& session) : HandlerHelper(session) {}
-
- void select();
- void commit();
- void rollback();
- };
-
- class DtxHandlerImpl : public DtxHandler, public HandlerHelper, private framing::StructHelper
- {
- std::string convert(const framing::Xid& xid);
-
- public:
- DtxHandlerImpl(SemanticState& session) : HandlerHelper(session) {}
-
- void select();
-
- framing::XaResult start(const framing::Xid& xid,
- bool join,
- bool resume);
-
- framing::XaResult end(const framing::Xid& xid,
- bool fail,
- bool suspend);
-
- framing::XaResult commit(const framing::Xid& xid,
- bool onePhase);
-
- void forget(const framing::Xid& xid);
-
- framing::DtxGetTimeoutResult getTimeout(const framing::Xid& xid);
-
- framing::XaResult prepare(const framing::Xid& xid);
-
- framing::DtxRecoverResult recover();
-
- framing::XaResult rollback(const framing::Xid& xid);
-
- void setTimeout(const framing::Xid& xid, uint32_t timeout);
- };
-
- ExchangeHandlerImpl exchangeImpl;
- QueueHandlerImpl queueImpl;
- MessageHandlerImpl messageImpl;
- ExecutionHandlerImpl executionImpl;
- TxHandlerImpl txImpl;
- DtxHandlerImpl dtxImpl;
-};
-}} // namespace qpid::broker
-
-
-
-#endif /*!_broker_SessionAdapter_h*/
diff --git a/cpp/src/qpid/broker/SessionContext.h b/cpp/src/qpid/broker/SessionContext.h
deleted file mode 100644
index 253ce8dcf2..0000000000
--- a/cpp/src/qpid/broker/SessionContext.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef QPID_BROKER_SESSIONCONTEXT_H
-#define QPID_BROKER_SESSIONCONTEXT_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-#include "qpid/framing/amqp_types.h"
-#include "qpid/sys/OutputControl.h"
-#include "qpid/broker/ConnectionState.h"
-#include "qpid/broker/OwnershipToken.h"
-#include "qpid/SessionId.h"
-
-#include <boost/noncopyable.hpp>
-
-namespace qpid {
-namespace broker {
-
-class SessionContext : public OwnershipToken, public sys::OutputControl
-{
- public:
- virtual ~SessionContext(){}
- virtual bool isLocal(const ConnectionToken* t) const = 0;
- virtual bool isAttached() const = 0;
- virtual ConnectionState& getConnection() = 0;
- virtual framing::AMQP_ClientProxy& getProxy() = 0;
- virtual Broker& getBroker() = 0;
- virtual uint16_t getChannel() const = 0;
- virtual const SessionId& getSessionId() const = 0;
- virtual void addPendingExecutionSync() = 0;
-};
-
-}} // namespace qpid::broker
-
-
-
-#endif /*!QPID_BROKER_SESSIONCONTEXT_H*/
diff --git a/cpp/src/qpid/broker/SessionHandler.cpp b/cpp/src/qpid/broker/SessionHandler.cpp
deleted file mode 100644
index 752fa55535..0000000000
--- a/cpp/src/qpid/broker/SessionHandler.cpp
+++ /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.
- *
- */
-
-#include "qpid/broker/SessionHandler.h"
-#include "qpid/broker/SessionState.h"
-#include "qpid/broker/Connection.h"
-#include "qpid/log/Statement.h"
-
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace broker {
-using namespace framing;
-using namespace std;
-using namespace qpid::sys;
-
-SessionHandler::SessionHandler(Connection& c, ChannelId ch)
- : amqp_0_10::SessionHandler(&c.getOutput(), ch),
- connection(c),
- proxy(out),
- clusterOrderProxy(c.getClusterOrderOutput() ? new SetChannelProxy(ch, c.getClusterOrderOutput()) : 0)
-{}
-
-SessionHandler::~SessionHandler() {}
-
-void SessionHandler::connectionException(framing::connection::CloseCode code, const std::string& msg) {
- // NOTE: must tell the error listener _before_ calling connection.close()
- if (connection.getErrorListener()) connection.getErrorListener()->connectionError(msg);
- connection.close(code, msg);
-}
-
-void SessionHandler::channelException(framing::session::DetachCode, const std::string& msg) {
- if (connection.getErrorListener()) connection.getErrorListener()->sessionError(getChannel(), msg);
-}
-
-void SessionHandler::executionException(framing::execution::ErrorCode, const std::string& msg) {
- if (connection.getErrorListener()) connection.getErrorListener()->sessionError(getChannel(), msg);
-}
-
-ConnectionState& SessionHandler::getConnection() { return connection; }
-
-const ConnectionState& SessionHandler::getConnection() const { return connection; }
-
-void SessionHandler::handleDetach() {
- amqp_0_10::SessionHandler::handleDetach();
- assert(&connection.getChannel(channel.get()) == this);
- if (session.get())
- connection.getBroker().getSessionManager().detach(session);
- assert(!session.get());
- connection.closeChannel(channel.get());
-}
-
-void SessionHandler::setState(const std::string& name, bool force) {
- assert(!session.get());
- SessionId id(connection.getUserId(), name);
- session = connection.broker.getSessionManager().attach(*this, id, force);
-}
-
-void SessionHandler::detaching()
-{
- assert(session.get());
- session->disableOutput();
-}
-
-FrameHandler* SessionHandler::getInHandler() { return session.get() ? &session->in : 0; }
-qpid::SessionState* SessionHandler::getState() { return session.get(); }
-
-void SessionHandler::readyToSend() {
- if (session.get()) session->readyToSend();
-}
-
-/**
- * Used by inter-broker bridges to set up session id and attach
- */
-void SessionHandler::attachAs(const std::string& name)
-{
- SessionId id(connection.getUserId(), name);
- SessionState::Configuration config = connection.broker.getSessionManager().getSessionConfig();
- // Delay creating management object till attached(). In a cluster,
- // only the active link broker calls attachAs but all brokers
- // receive the subsequent attached() call.
- session.reset(new SessionState(connection.getBroker(), *this, id, config, true));
- sendAttach(false);
-}
-
-/**
- * TODO: this is a little ugly, fix it; its currently still relied on
- * for 'push' bridges
- */
-void SessionHandler::attached(const std::string& name)
-{
- if (session.get()) {
- session->addManagementObject(); // Delayed from attachAs()
- amqp_0_10::SessionHandler::attached(name);
- } else {
- SessionId id(connection.getUserId(), name);
- SessionState::Configuration config = connection.broker.getSessionManager().getSessionConfig();
- session.reset(new SessionState(connection.getBroker(), *this, id, config));
- markReadyToSend();
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SessionHandler.h b/cpp/src/qpid/broker/SessionHandler.h
deleted file mode 100644
index ca6d6bb193..0000000000
--- a/cpp/src/qpid/broker/SessionHandler.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef QPID_BROKER_SESSIONHANDLER_H
-#define QPID_BROKER_SESSIONHANDLER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/amqp_0_10/SessionHandler.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-
-namespace qpid {
-class SessionState;
-
-namespace broker {
-
-class Connection;
-class ConnectionState;
-class SessionState;
-
-/**
- * A SessionHandler is associated with each active channel. It
- * receives incoming frames, handles session controls and manages the
- * association between the channel and a session.
- */
-class SessionHandler : public amqp_0_10::SessionHandler {
- public:
- SessionHandler(Connection&, framing::ChannelId);
- ~SessionHandler();
-
- /** Get broker::SessionState */
- SessionState* getSession() { return session.get(); }
- const SessionState* getSession() const { return session.get(); }
-
- ConnectionState& getConnection();
- const ConnectionState& getConnection() const;
-
- framing::AMQP_ClientProxy& getProxy() { return proxy; }
- const framing::AMQP_ClientProxy& getProxy() const { return proxy; }
-
- /**
- * If commands are sent based on the local time (e.g. in timers), they don't have
- * a well-defined ordering across cluster nodes.
- * This proxy is for sending such commands. In a clustered broker it will take steps
- * to synchronize command order across the cluster. In a stand-alone broker
- * it is just a synonym for getProxy()
- */
- framing::AMQP_ClientProxy& getClusterOrderProxy() {
- return clusterOrderProxy.get() ? *clusterOrderProxy : proxy;
- }
-
- virtual void handleDetach();
- void attached(const std::string& name);//used by 'pushing' inter-broker bridges
- void attachAs(const std::string& name);//used by 'pulling' inter-broker bridges
-
- protected:
- virtual void setState(const std::string& sessionName, bool force);
- virtual qpid::SessionState* getState();
- virtual framing::FrameHandler* getInHandler();
- virtual void connectionException(framing::connection::CloseCode code, const std::string& msg);
- virtual void channelException(framing::session::DetachCode, const std::string& msg);
- virtual void executionException(framing::execution::ErrorCode, const std::string& msg);
- virtual void detaching();
- virtual void readyToSend();
-
- private:
- struct SetChannelProxy : public framing::AMQP_ClientProxy { // Proxy that sets the channel.
- framing::ChannelHandler setChannel;
- SetChannelProxy(uint16_t ch, framing::FrameHandler* out)
- : framing::AMQP_ClientProxy(setChannel), setChannel(ch, out) {}
- };
-
- Connection& connection;
- framing::AMQP_ClientProxy proxy;
- std::auto_ptr<SessionState> session;
- std::auto_ptr<SetChannelProxy> clusterOrderProxy;
-};
-
-}} // namespace qpid::broker
-
-
-
-#endif /*!QPID_BROKER_SESSIONHANDLER_H*/
diff --git a/cpp/src/qpid/broker/SessionManager.cpp b/cpp/src/qpid/broker/SessionManager.cpp
deleted file mode 100644
index 8cc58571af..0000000000
--- a/cpp/src/qpid/broker/SessionManager.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/broker/SessionManager.h"
-#include "qpid/broker/SessionState.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include "qpid/log/Helpers.h"
-#include "qpid/memory.h"
-
-#include <boost/bind.hpp>
-#include <boost/range.hpp>
-
-#include <algorithm>
-#include <functional>
-#include <ostream>
-
-namespace qpid {
-namespace broker {
-
-using boost::intrusive_ptr;
-using namespace sys;
-using namespace framing;
-
-SessionManager::SessionManager(const SessionState::Configuration& c, Broker& b)
- : config(c), broker(b) {}
-
-SessionManager::~SessionManager() {
- detached.clear(); // Must clear before destructor as session dtor will call forget()
-}
-
-std::auto_ptr<SessionState> SessionManager::attach(SessionHandler& h, const SessionId& id, bool/*force*/) {
- Mutex::ScopedLock l(lock);
- eraseExpired(); // Clean up expired table
- std::pair<Attached::iterator, bool> insert = attached.insert(id);
- if (!insert.second)
- throw SessionBusyException(QPID_MSG("Session already attached: " << id));
- Detached::iterator i = std::find(detached.begin(), detached.end(), id);
- std::auto_ptr<SessionState> state;
- if (i == detached.end())
- state.reset(new SessionState(broker, h, id, config));
- else {
- state.reset(detached.release(i).release());
- state->attach(h);
- }
- return state;
- // FIXME aconway 2008-04-29: implement force
-}
-
-void SessionManager::detach(std::auto_ptr<SessionState> session) {
- Mutex::ScopedLock l(lock);
- attached.erase(session->getId());
- session->detach();
- if (session->getTimeout() > 0) {
- session->expiry = AbsTime(now(),session->getTimeout()*TIME_SEC);
- if (session->mgmtObject != 0)
- session->mgmtObject->set_expireTime ((uint64_t) Duration (EPOCH, session->expiry));
- detached.push_back(session.release()); // In expiry order
- eraseExpired();
-}
-}
-
-void SessionManager::forget(const SessionId& id) {
- Mutex::ScopedLock l(lock);
- attached.erase(id);
-}
-
-void SessionManager::eraseExpired() {
- // Called with lock held.
- if (!detached.empty()) {
- // This used to use a more elegant invocation of std::lower_bound
- // but violated the strict weak ordering rule which Visual Studio
- // enforced. See QPID-1424 for more info should you be tempted to
- // replace the loop with something more elegant.
- AbsTime now = AbsTime::now();
- Detached::iterator keep = detached.begin();
- while ((keep != detached.end()) && ((*keep).expiry < now))
- keep++;
- if (detached.begin() != keep) {
- QPID_LOG(debug, "Expiring sessions: " << log::formatList(detached.begin(), keep));
- detached.erase(detached.begin(), keep);
- }
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SessionManager.h b/cpp/src/qpid/broker/SessionManager.h
deleted file mode 100644
index db88e7ec10..0000000000
--- a/cpp/src/qpid/broker/SessionManager.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef QPID_BROKER_SESSIONMANAGER_H
-#define QPID_BROKER_SESSIONMANAGER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include <qpid/SessionState.h>
-#include <qpid/sys/Time.h>
-#include <qpid/sys/Mutex.h>
-#include <qpid/RefCounted.h>
-
-#include <set>
-#include <vector>
-#include <memory>
-
-#include <boost/noncopyable.hpp>
-#include <boost/ptr_container/ptr_vector.hpp>
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-class Broker;
-class SessionState;
-class SessionHandler;
-
-/**
- * Create and manage SessionState objects.
- */
-class SessionManager : private boost::noncopyable {
- public:
- SessionManager(const qpid::SessionState::Configuration&, Broker&);
-
- ~SessionManager();
-
- /** Open a new active session, caller takes ownership */
- std::auto_ptr<SessionState> attach(SessionHandler& h, const SessionId& id, bool/*force*/);
-
- /** Return a detached session to the manager, start the timeout counter. */
- void detach(std::auto_ptr<SessionState>);
-
- /** Forget about an attached session. Called by SessionState destructor. */
- void forget(const SessionId&);
-
- Broker& getBroker() const { return broker; }
-
- const qpid::SessionState::Configuration& getSessionConfig() const { return config; }
-
- private:
- typedef boost::ptr_vector<SessionState> Detached; // Sorted in expiry order.
- typedef std::set<SessionId> Attached;
-
- void eraseExpired();
-
- sys::Mutex lock;
- Detached detached;
- Attached attached;
- qpid::SessionState::Configuration config;
- Broker& broker;
-};
-
-
-
-}} // namespace qpid::broker
-
-
-
-
-
-#endif /*!QPID_BROKER_SESSIONMANAGER_H*/
diff --git a/cpp/src/qpid/broker/SessionOutputException.h b/cpp/src/qpid/broker/SessionOutputException.h
deleted file mode 100644
index 7c1c5de926..0000000000
--- a/cpp/src/qpid/broker/SessionOutputException.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef QPID_BROKER_SESSIONOUTPUTEXCEPTION_H
-#define QPID_BROKER_SESSIONOUTPUTEXCEPTION_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/Exception.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * This exception is used to signal 'session' exceptions (aka
- * execution exceptions in AMQP 0-10 terms) that occur during output
- * processing. It simply allows the channel of the session to be
- * specified in addition to the other details. Special treatment is
- * required at present because the output processing chain is
- * different from that which handles incoming commands (specifically
- * AggregateOutput cannot reasonably handle exceptions as it has no
- * context).
- */
-struct SessionOutputException : qpid::SessionException
-{
- const uint16_t channel;
- SessionOutputException(const qpid::SessionException& e, uint16_t c) : qpid::SessionException(e.code, e.getMessage()), channel(c) {}
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_SESSIONOUTPUTEXCEPTION_H*/
diff --git a/cpp/src/qpid/broker/SessionState.cpp b/cpp/src/qpid/broker/SessionState.cpp
deleted file mode 100644
index 957d5bd4d2..0000000000
--- a/cpp/src/qpid/broker/SessionState.cpp
+++ /dev/null
@@ -1,591 +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.
- *
- */
-#include "qpid/broker/SessionState.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/ConnectionState.h"
-#include "qpid/broker/DeliveryRecord.h"
-#include "qpid/broker/SessionManager.h"
-#include "qpid/broker/SessionHandler.h"
-#include "qpid/broker/RateFlowcontrol.h"
-#include "qpid/sys/Timer.h"
-#include "qpid/framing/AMQContentBody.h"
-#include "qpid/framing/AMQHeaderBody.h"
-#include "qpid/framing/AMQMethodBody.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/framing/ServerInvoker.h"
-#include "qpid/log/Statement.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-
-#include <boost/bind.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace qpid {
-namespace broker {
-
-using namespace framing;
-using sys::Mutex;
-using boost::intrusive_ptr;
-using qpid::management::ManagementAgent;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::AbsTime;
-//using qpid::sys::Timer;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-SessionState::SessionState(
- Broker& b, SessionHandler& h, const SessionId& id,
- const SessionState::Configuration& config, bool delayManagement)
- : qpid::SessionState(id, config),
- broker(b), handler(&h),
- semanticState(*this, *this),
- adapter(semanticState),
- msgBuilder(&broker.getStore()),
- mgmtObject(0),
- rateFlowcontrol(0),
- asyncCommandCompleter(new AsyncCommandCompleter(this))
-{
- uint32_t maxRate = broker.getOptions().maxSessionRate;
- if (maxRate) {
- if (handler->getConnection().getClientThrottling()) {
- rateFlowcontrol.reset(new RateFlowcontrol(maxRate));
- } else {
- QPID_LOG(warning, getId() << ": Unable to flow control client - client doesn't support");
- }
- }
- if (!delayManagement) addManagementObject();
- attach(h);
-}
-
-void SessionState::addManagementObject() {
- if (GetManagementObject()) return; // Already added.
- Manageable* parent = broker.GetVhostObject ();
- if (parent != 0) {
- ManagementAgent* agent = getBroker().getManagementAgent();
- if (agent != 0) {
- mgmtObject = new _qmf::Session
- (agent, this, parent, getId().getName());
- mgmtObject->set_attached (0);
- mgmtObject->set_detachedLifespan (0);
- mgmtObject->clr_expireTime();
- if (rateFlowcontrol)
- mgmtObject->set_maxClientRate(rateFlowcontrol->getRate());
- agent->addObject(mgmtObject);
- }
- }
-}
-
-SessionState::~SessionState() {
- asyncCommandCompleter->cancel();
- semanticState.closed();
- if (mgmtObject != 0)
- mgmtObject->resourceDestroy ();
-
- if (flowControlTimer)
- flowControlTimer->cancel();
-}
-
-AMQP_ClientProxy& SessionState::getProxy() {
- assert(isAttached());
- return handler->getProxy();
-}
-
-uint16_t SessionState::getChannel() const {
- assert(isAttached());
- return handler->getChannel();
-}
-
-ConnectionState& SessionState::getConnection() {
- assert(isAttached());
- return handler->getConnection();
-}
-
-bool SessionState::isLocal(const ConnectionToken* t) const
-{
- return isAttached() && &(handler->getConnection()) == t;
-}
-
-void SessionState::detach() {
- QPID_LOG(debug, getId() << ": detached on broker.");
- asyncCommandCompleter->detached();
- disableOutput();
- handler = 0;
- if (mgmtObject != 0)
- mgmtObject->set_attached (0);
-}
-
-void SessionState::disableOutput()
-{
- semanticState.detached(); //prevents further activateOutput calls until reattached
-}
-
-void SessionState::attach(SessionHandler& h) {
- QPID_LOG(debug, getId() << ": attached on broker.");
- handler = &h;
- if (mgmtObject != 0)
- {
- mgmtObject->set_attached (1);
- mgmtObject->set_connectionRef (h.getConnection().GetManagementObject()->getObjectId());
- mgmtObject->set_channelId (h.getChannel());
- }
- asyncCommandCompleter->attached();
-}
-
-void SessionState::abort() {
- if (isAttached())
- getConnection().outputTasks.abort();
-}
-
-void SessionState::activateOutput() {
- if (isAttached())
- getConnection().outputTasks.activateOutput();
-}
-
-void SessionState::giveReadCredit(int32_t credit) {
- if (isAttached())
- getConnection().outputTasks.giveReadCredit(credit);
-}
-
-ManagementObject* SessionState::GetManagementObject (void) const
-{
- return (ManagementObject*) mgmtObject;
-}
-
-Manageable::status_t SessionState::ManagementMethod (uint32_t methodId,
- Args& /*args*/,
- string& /*text*/)
-{
- Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD;
-
- switch (methodId)
- {
- case _qmf::Session::METHOD_DETACH :
- if (handler != 0) {
- handler->sendDetach();
- }
- status = Manageable::STATUS_OK;
- break;
-
- case _qmf::Session::METHOD_CLOSE :
- /*
- if (handler != 0)
- {
- handler->getConnection().closeChannel(handler->getChannel());
- }
- status = Manageable::STATUS_OK;
- break;
- */
-
- case _qmf::Session::METHOD_SOLICITACK :
- case _qmf::Session::METHOD_RESETLIFESPAN :
- status = Manageable::STATUS_NOT_IMPLEMENTED;
- break;
- }
-
- return status;
-}
-
-void SessionState::handleCommand(framing::AMQMethodBody* method, const SequenceNumber& id) {
- currentCommandComplete = true; // assumed, can be overridden by invoker method (this sucks).
- Invoker::Result invocation = invoke(adapter, *method);
- if (currentCommandComplete) receiverCompleted(id);
-
- if (!invocation.wasHandled()) {
- throw NotImplementedException(QPID_MSG("Not implemented: " << *method));
- } else if (invocation.hasResult()) {
- getProxy().getExecution().result(id, invocation.getResult());
- }
-
- if (method->isSync() && currentCommandComplete) {
- sendAcceptAndCompletion();
- }
-}
-
-struct ScheduledCreditTask : public sys::TimerTask {
- sys::Timer& timer;
- SessionState& sessionState;
- ScheduledCreditTask(const qpid::sys::Duration& d, sys::Timer& t,
- SessionState& s) :
- TimerTask(d,"ScheduledCredit"),
- timer(t),
- sessionState(s)
- {}
-
- void fire() {
- // This is the best we can currently do to avoid a destruction/fire race
- sessionState.getConnection().requestIOProcessing(boost::bind(&ScheduledCreditTask::sendCredit, this));
- }
-
- void sendCredit() {
- if ( !sessionState.processSendCredit(0) ) {
- QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit");
- setupNextFire();
- timer.add(this);
- }
- }
-};
-
-void SessionState::handleContent(AMQFrame& frame, const SequenceNumber& id)
-{
- if (frame.getBof() && frame.getBos()) //start of frameset
- msgBuilder.start(id);
- intrusive_ptr<Message> msg(msgBuilder.getMessage());
- msgBuilder.handle(frame);
- if (frame.getEof() && frame.getEos()) {//end of frameset
- if (frame.getBof()) {
- //i.e this is a just a command frame, add a dummy header
- AMQFrame header((AMQHeaderBody()));
- header.setBof(false);
- header.setEof(false);
- msg->getFrames().append(header);
- }
- msg->setPublisher(&getConnection());
- msg->getIngressCompletion().begin();
- semanticState.handle(msg);
- msgBuilder.end();
- IncompleteIngressMsgXfer xfer(this, msg);
- msg->getIngressCompletion().end(xfer); // allows msg to complete xfer
- }
-
- // Handle producer session flow control
- if (rateFlowcontrol && frame.getBof() && frame.getBos()) {
- if ( !processSendCredit(1) ) {
- QPID_LOG(debug, getId() << ": Schedule sending credit");
- sys::Timer& timer = getBroker().getTimer();
- // Use heuristic for scheduled credit of time for 50 messages, but not longer than 500ms
- sys::Duration d = std::min(sys::TIME_SEC * 50 / rateFlowcontrol->getRate(), 500 * sys::TIME_MSEC);
- flowControlTimer = new ScheduledCreditTask(d, timer, *this);
- timer.add(flowControlTimer);
- }
- }
-}
-
-bool SessionState::processSendCredit(uint32_t msgs)
-{
- qpid::sys::ScopedLock<Mutex> l(rateLock);
- // Check for violating flow control
- if ( msgs > 0 && rateFlowcontrol->flowStopped() ) {
- QPID_LOG(warning, getId() << ": producer throttling violation");
- // TODO: Probably do message.stop("") first time then disconnect
- // See comment on getClusterOrderProxy() in .h file
- getClusterOrderProxy().getMessage().stop("");
- return true;
- }
- AbsTime now = AbsTime::now();
- uint32_t sendCredit = rateFlowcontrol->receivedMessage(now, msgs);
- if (mgmtObject) mgmtObject->dec_clientCredit(msgs);
- if ( sendCredit>0 ) {
- QPID_LOG(debug, getId() << ": send producer credit " << sendCredit);
- getClusterOrderProxy().getMessage().flow("", 0, sendCredit);
- rateFlowcontrol->sentCredit(now, sendCredit);
- if (mgmtObject) mgmtObject->inc_clientCredit(sendCredit);
- return true;
- } else {
- return !rateFlowcontrol->flowStopped() ;
- }
-}
-
-void SessionState::sendAcceptAndCompletion()
-{
- if (!accepted.empty()) {
- getProxy().getMessage().accept(accepted);
- accepted.clear();
- }
- sendCompletion();
-}
-
-/** Invoked when the given inbound message is finished being processed
- * by all interested parties (eg. it is done being enqueued to all queues,
- * its credit has been accounted for, etc). At this point, msg is considered
- * by this receiver as 'completed' (as defined by AMQP 0_10)
- */
-void SessionState::completeRcvMsg(SequenceNumber id,
- bool requiresAccept,
- bool requiresSync)
-{
- bool callSendCompletion = false;
- receiverCompleted(id);
- if (requiresAccept)
- // will cause msg's seq to appear in the next message.accept we send.
- accepted.add(id);
-
- // Are there any outstanding Execution.Sync commands pending the
- // completion of this msg? If so, complete them.
- while (!pendingExecutionSyncs.empty() &&
- receiverGetIncomplete().front() >= pendingExecutionSyncs.front()) {
- const SequenceNumber id = pendingExecutionSyncs.front();
- pendingExecutionSyncs.pop();
- QPID_LOG(debug, getId() << ": delayed execution.sync " << id << " is completed.");
- receiverCompleted(id);
- callSendCompletion = true; // likely peer is pending for this completion.
- }
-
- // if the sender has requested immediate notification of the completion...
- if (requiresSync) {
- sendAcceptAndCompletion();
- } else if (callSendCompletion) {
- sendCompletion();
- }
-}
-
-void SessionState::handleIn(AMQFrame& frame) {
- SequenceNumber commandId = receiverGetCurrent();
- //TODO: make command handling more uniform, regardless of whether
- //commands carry content.
- AMQMethodBody* m = frame.getMethod();
- if (m == 0 || m->isContentBearing()) {
- handleContent(frame, commandId);
- } else if (frame.getBof() && frame.getEof()) {
- handleCommand(frame.getMethod(), commandId);
- } else {
- throw InternalErrorException("Cannot handle multi-frame command segments yet");
- }
-}
-
-void SessionState::handleOut(AMQFrame& frame) {
- assert(handler);
- handler->out(frame);
-}
-
-void SessionState::deliver(DeliveryRecord& msg, bool sync)
-{
- uint32_t maxFrameSize = getConnection().getFrameMax();
- assert(senderGetCommandPoint().offset == 0);
- SequenceNumber commandId = senderGetCommandPoint().command;
- msg.deliver(getProxy().getHandler(), commandId, maxFrameSize);
- assert(senderGetCommandPoint() == SessionPoint(commandId+1, 0)); // Delivery has moved sendPoint.
- if (sync) {
- AMQP_ClientProxy::Execution& p(getProxy().getExecution());
- Proxy::ScopedSync s(p);
- p.sync();
- }
-}
-
-void SessionState::sendCompletion() {
- handler->sendCompletion();
-}
-
-void SessionState::senderCompleted(const SequenceSet& commands) {
- qpid::SessionState::senderCompleted(commands);
- semanticState.completed(commands);
-}
-
-void SessionState::readyToSend() {
- QPID_LOG(debug, getId() << ": ready to send, activating output.");
- assert(handler);
- semanticState.attached();
- if (rateFlowcontrol) {
- qpid::sys::ScopedLock<Mutex> l(rateLock);
- // Issue initial credit - use a heuristic here issue min of 300 messages or 1 secs worth
- uint32_t credit = std::min(rateFlowcontrol->getRate(), 300U);
- QPID_LOG(debug, getId() << ": Issuing producer message credit " << credit);
- // See comment on getClusterOrderProxy() in .h file
- getClusterOrderProxy().getMessage().setFlowMode("", 0);
- getClusterOrderProxy().getMessage().flow("", 0, credit);
- rateFlowcontrol->sentCredit(AbsTime::now(), credit);
- if (mgmtObject) mgmtObject->inc_clientCredit(credit);
- }
-}
-
-Broker& SessionState::getBroker() { return broker; }
-
-// Session resume is not fully implemented so it is useless to set a
-// non-0 timeout. Moreover it creates problems in a cluster because
-// dead sessions are kept and interfere with failover.
-void SessionState::setTimeout(uint32_t) { }
-
-framing::AMQP_ClientProxy& SessionState::getClusterOrderProxy() {
- return handler->getClusterOrderProxy();
-}
-
-
-// Current received command is an execution.sync command.
-// Complete this command only when all preceding commands have completed.
-// (called via the invoker() in handleCommand() above)
-void SessionState::addPendingExecutionSync()
-{
- SequenceNumber syncCommandId = receiverGetCurrent();
- if (receiverGetIncomplete().front() < syncCommandId) {
- currentCommandComplete = false;
- pendingExecutionSyncs.push(syncCommandId);
- asyncCommandCompleter->flushPendingMessages();
- QPID_LOG(debug, getId() << ": delaying completion of execution.sync " << syncCommandId);
- }
-}
-
-
-/** factory for creating a reference-counted IncompleteIngressMsgXfer object
- * which will be attached to a message that will be completed asynchronously.
- */
-boost::intrusive_ptr<AsyncCompletion::Callback>
-SessionState::IncompleteIngressMsgXfer::clone()
-{
- boost::intrusive_ptr<SessionState::IncompleteIngressMsgXfer> cb(new SessionState::IncompleteIngressMsgXfer(session, msg));
-
- // Optimization: this routine is *only* invoked when the message needs to be asynchronously completed.
- // If the client is pending the message.transfer completion, flush now to force immediate write to journal.
- if (requiresSync)
- msg->flush();
- else {
- // otherwise, we need to track this message in order to flush it if an execution.sync arrives
- // before it has been completed (see flushPendingMessages())
- pending = true;
- completerContext->addPendingMessage(msg);
- }
- return cb;
-}
-
-
-/** Invoked by the asynchronous completer associated with a received
- * msg that is pending Completion. May be invoked by the IO thread
- * (sync == true), or some external thread (!sync).
- */
-void SessionState::IncompleteIngressMsgXfer::completed(bool sync)
-{
- if (pending) completerContext->deletePendingMessage(id);
- if (!sync) {
- /** note well: this path may execute in any thread. It is safe to access
- * the scheduledCompleterContext, since *this has a shared pointer to it.
- * but not session!
- */
- session = 0;
- QPID_LOG(debug, ": async completion callback scheduled for msg seq=" << id);
- completerContext->scheduleMsgCompletion(id, requiresAccept, requiresSync);
- } else {
- // this path runs directly from the ac->end() call in handleContent() above,
- // so *session is definately valid.
- if (session->isAttached()) {
- QPID_LOG(debug, ": receive completed for msg seq=" << id);
- session->completeRcvMsg(id, requiresAccept, requiresSync);
- }
- }
- completerContext = boost::intrusive_ptr<AsyncCommandCompleter>();
-}
-
-
-/** Scheduled from an asynchronous command's completed callback to run on
- * the IO thread.
- */
-void SessionState::AsyncCommandCompleter::schedule(boost::intrusive_ptr<AsyncCommandCompleter> ctxt)
-{
- ctxt->completeCommands();
-}
-
-
-/** Track an ingress message that is pending completion */
-void SessionState::AsyncCommandCompleter::addPendingMessage(boost::intrusive_ptr<Message> msg)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- std::pair<SequenceNumber, boost::intrusive_ptr<Message> > item(msg->getCommandId(), msg);
- bool unique = pendingMsgs.insert(item).second;
- assert(unique);
-}
-
-
-/** pending message has completed */
-void SessionState::AsyncCommandCompleter::deletePendingMessage(SequenceNumber id)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- pendingMsgs.erase(id);
-}
-
-
-/** done when an execution.sync arrives */
-void SessionState::AsyncCommandCompleter::flushPendingMessages()
-{
- std::map<SequenceNumber, boost::intrusive_ptr<Message> > copy;
- {
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- pendingMsgs.swap(copy); // we've only tracked these in case a flush is needed, so nuke 'em now.
- }
- // drop lock, so it is safe to call "flush()"
- for (std::map<SequenceNumber, boost::intrusive_ptr<Message> >::iterator i = copy.begin();
- i != copy.end(); ++i) {
- i->second->flush();
- }
-}
-
-
-/** mark an ingress Message.Transfer command as completed.
- * This method must be thread safe - it may run on any thread.
- */
-void SessionState::AsyncCommandCompleter::scheduleMsgCompletion(SequenceNumber cmd,
- bool requiresAccept,
- bool requiresSync)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
-
- if (session && isAttached) {
- MessageInfo msg(cmd, requiresAccept, requiresSync);
- completedMsgs.push_back(msg);
- if (completedMsgs.size() == 1) {
- session->getConnection().requestIOProcessing(boost::bind(&schedule,
- session->asyncCommandCompleter));
- }
- }
-}
-
-
-/** Cause the session to complete all completed commands.
- * Executes on the IO thread.
- */
-void SessionState::AsyncCommandCompleter::completeCommands()
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
-
- // when session is destroyed, it clears the session pointer via cancel().
- if (session && session->isAttached()) {
- for (std::vector<MessageInfo>::iterator msg = completedMsgs.begin();
- msg != completedMsgs.end(); ++msg) {
- session->completeRcvMsg(msg->cmd, msg->requiresAccept, msg->requiresSync);
- }
- }
- completedMsgs.clear();
-}
-
-
-/** cancel any pending calls to scheduleComplete */
-void SessionState::AsyncCommandCompleter::cancel()
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- session = 0;
-}
-
-
-/** inform the completer that the session has attached,
- * allows command completion scheduling from any thread */
-void SessionState::AsyncCommandCompleter::attached()
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- isAttached = true;
-}
-
-
-/** inform the completer that the session has detached,
- * disables command completion scheduling from any thread */
-void SessionState::AsyncCommandCompleter::detached()
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- isAttached = false;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SessionState.h b/cpp/src/qpid/broker/SessionState.h
deleted file mode 100644
index b43df0c0aa..0000000000
--- a/cpp/src/qpid/broker/SessionState.h
+++ /dev/null
@@ -1,284 +0,0 @@
-#ifndef QPID_BROKER_SESSION_H
-#define QPID_BROKER_SESSION_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/SessionState.h"
-#include "qpid/framing/FrameHandler.h"
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/sys/Time.h"
-#include "qpid/management/Manageable.h"
-#include "qmf/org/apache/qpid/broker/Session.h"
-#include "qpid/broker/SessionAdapter.h"
-#include "qpid/broker/DeliveryAdapter.h"
-#include "qpid/broker/AsyncCompletion.h"
-#include "qpid/broker/MessageBuilder.h"
-#include "qpid/broker/SessionContext.h"
-#include "qpid/broker/SemanticState.h"
-#include "qpid/sys/Monitor.h"
-
-#include <boost/noncopyable.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
-
-#include <set>
-#include <vector>
-#include <ostream>
-
-namespace qpid {
-
-namespace framing {
-class AMQP_ClientProxy;
-}
-
-namespace sys {
-class TimerTask;
-}
-
-namespace broker {
-
-class Broker;
-class ConnectionState;
-class Message;
-class SessionHandler;
-class SessionManager;
-class RateFlowcontrol;
-
-/**
- * Broker-side session state includes session's handler chains, which
- * may themselves have state.
- */
-class SessionState : public qpid::SessionState,
- public SessionContext,
- public DeliveryAdapter,
- public management::Manageable,
- public framing::FrameHandler::InOutHandler
-{
- public:
- SessionState(Broker&, SessionHandler&, const SessionId&,
- const SessionState::Configuration&, bool delayManagement=false);
- ~SessionState();
- bool isAttached() const { return handler; }
-
- void detach();
- void attach(SessionHandler& handler);
- void disableOutput();
-
- /** @pre isAttached() */
- framing::AMQP_ClientProxy& getProxy();
-
- /** @pre isAttached() */
- uint16_t getChannel() const;
-
- /** @pre isAttached() */
- ConnectionState& getConnection();
- bool isLocal(const ConnectionToken* t) const;
-
- Broker& getBroker();
-
- void setTimeout(uint32_t seconds);
-
- /** OutputControl **/
- void abort();
- void activateOutput();
- void giveReadCredit(int32_t);
-
- void senderCompleted(const framing::SequenceSet& ranges);
-
- void sendCompletion();
-
- //delivery adapter methods:
- void deliver(DeliveryRecord&, bool sync);
-
- // Manageable entry points
- management::ManagementObject* GetManagementObject (void) const;
- management::Manageable::status_t
- ManagementMethod (uint32_t methodId, management::Args& args, std::string&);
-
- void readyToSend();
-
- // Used by cluster to create replica sessions.
- SemanticState& getSemanticState() { return semanticState; }
- boost::intrusive_ptr<Message> getMessageInProgress() { return msgBuilder.getMessage(); }
- SessionAdapter& getSessionAdapter() { return adapter; }
-
- bool processSendCredit(uint32_t msgs);
-
- const SessionId& getSessionId() const { return getId(); }
-
- // Used by ExecutionHandler sync command processing. Notifies
- // the SessionState of a received Execution.Sync command.
- void addPendingExecutionSync();
-
- // Used to delay creation of management object for sessions
- // belonging to inter-broker bridges
- void addManagementObject();
-
- private:
- void handleCommand(framing::AMQMethodBody* method, const framing::SequenceNumber& id);
- void handleContent(framing::AMQFrame& frame, const framing::SequenceNumber& id);
-
- // indicate that the given ingress msg has been completely received by the
- // broker, and the msg's message.transfer command can be considered completed.
- void completeRcvMsg(SequenceNumber id, bool requiresAccept, bool requiresSync);
-
- void handleIn(framing::AMQFrame& frame);
- void handleOut(framing::AMQFrame& frame);
-
- // End of the input & output chains.
- void handleInLast(framing::AMQFrame& frame);
- void handleOutLast(framing::AMQFrame& frame);
-
- void sendAcceptAndCompletion();
-
- /**
- * If commands are sent based on the local time (e.g. in timers), they don't have
- * a well-defined ordering across cluster nodes.
- * This proxy is for sending such commands. In a clustered broker it will take steps
- * to synchronize command order across the cluster. In a stand-alone broker
- * it is just a synonym for getProxy()
- */
- framing::AMQP_ClientProxy& getClusterOrderProxy();
-
- Broker& broker;
- SessionHandler* handler;
- sys::AbsTime expiry; // Used by SessionManager.
- SemanticState semanticState;
- SessionAdapter adapter;
- MessageBuilder msgBuilder;
- qmf::org::apache::qpid::broker::Session* mgmtObject;
- qpid::framing::SequenceSet accepted;
-
- // State used for producer flow control (rate limited)
- qpid::sys::Mutex rateLock;
- boost::scoped_ptr<RateFlowcontrol> rateFlowcontrol;
- boost::intrusive_ptr<sys::TimerTask> flowControlTimer;
-
- // sequence numbers for pending received Execution.Sync commands
- std::queue<SequenceNumber> pendingExecutionSyncs;
- bool currentCommandComplete;
-
- /** This class provides a context for completing asynchronous commands in a thread
- * safe manner. Asynchronous commands save their completion state in this class.
- * This class then schedules the completeCommands() method in the IO thread.
- * While running in the IO thread, completeCommands() may safely complete all
- * saved commands without the risk of colliding with other operations on this
- * SessionState.
- */
- class AsyncCommandCompleter : public RefCounted {
- private:
- SessionState *session;
- bool isAttached;
- qpid::sys::Mutex completerLock;
-
- // special-case message.transfer commands for optimization
- struct MessageInfo {
- SequenceNumber cmd; // message.transfer command id
- bool requiresAccept;
- bool requiresSync;
- MessageInfo(SequenceNumber c, bool a, bool s)
- : cmd(c), requiresAccept(a), requiresSync(s) {}
- };
- std::vector<MessageInfo> completedMsgs;
- // If an ingress message does not require a Sync, we need to
- // hold a reference to it in case an Execution.Sync command is received and we
- // have to manually flush the message.
- std::map<SequenceNumber, boost::intrusive_ptr<Message> > pendingMsgs;
-
- /** complete all pending commands, runs in IO thread */
- void completeCommands();
-
- /** for scheduling a run of "completeCommands()" on the IO thread */
- static void schedule(boost::intrusive_ptr<AsyncCommandCompleter>);
-
- public:
- AsyncCommandCompleter(SessionState *s) : session(s), isAttached(s->isAttached()) {};
- ~AsyncCommandCompleter() {};
-
- /** track a message pending ingress completion */
- void addPendingMessage(boost::intrusive_ptr<Message> m);
- void deletePendingMessage(SequenceNumber id);
- void flushPendingMessages();
- /** schedule the processing of a completed ingress message.transfer command */
- void scheduleMsgCompletion(SequenceNumber cmd,
- bool requiresAccept,
- bool requiresSync);
- void cancel(); // called by SessionState destructor.
- void attached(); // called by SessionState on attach()
- void detached(); // called by SessionState on detach()
- };
- boost::intrusive_ptr<AsyncCommandCompleter> asyncCommandCompleter;
-
- /** Abstract class that represents a single asynchronous command that is
- * pending completion.
- */
- class AsyncCommandContext : public AsyncCompletion::Callback
- {
- public:
- AsyncCommandContext( SessionState *ss, SequenceNumber _id )
- : id(_id), completerContext(ss->asyncCommandCompleter) {}
- virtual ~AsyncCommandContext() {}
-
- protected:
- SequenceNumber id;
- boost::intrusive_ptr<AsyncCommandCompleter> completerContext;
- };
-
- /** incomplete Message.transfer commands - inbound to broker from client
- */
- class IncompleteIngressMsgXfer : public SessionState::AsyncCommandContext
- {
- public:
- IncompleteIngressMsgXfer( SessionState *ss,
- boost::intrusive_ptr<Message> m )
- : AsyncCommandContext(ss, m->getCommandId()),
- session(ss),
- msg(m),
- requiresAccept(m->requiresAccept()),
- requiresSync(m->getFrames().getMethod()->isSync()),
- pending(false) {}
- virtual ~IncompleteIngressMsgXfer() {};
-
- virtual void completed(bool);
- virtual boost::intrusive_ptr<AsyncCompletion::Callback> clone();
-
- private:
- SessionState *session; // only valid if sync flag in callback is true
- boost::intrusive_ptr<Message> msg;
- bool requiresAccept;
- bool requiresSync;
- bool pending; // true if msg saved on pending list...
- };
-
- friend class SessionManager;
-};
-
-
-inline std::ostream& operator<<(std::ostream& out, const SessionState& session) {
- return out << session.getId();
-}
-
-}} // namespace qpid::broker
-
-
-
-#endif /*!QPID_BROKER_SESSION_H*/
diff --git a/cpp/src/qpid/broker/SignalHandler.cpp b/cpp/src/qpid/broker/SignalHandler.cpp
deleted file mode 100644
index 16c141f21c..0000000000
--- a/cpp/src/qpid/broker/SignalHandler.cpp
+++ /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.
- *
- */
-#include "qpid/broker/SignalHandler.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/sys/Mutex.h"
-#include <signal.h>
-
-namespace qpid {
-namespace broker {
-
-// Lock is to ensure that broker is not concurrently set to 0 and
-// deleted while we are in a call to broker->shutdown()
-
-sys::Mutex brokerLock;
-Broker* SignalHandler::broker;
-
-void SignalHandler::setBroker(Broker* b) {
- sys::Mutex::ScopedLock l(brokerLock);
- broker = b;
- signal(SIGINT,shutdownHandler);
- signal(SIGTERM, shutdownHandler);
- signal(SIGHUP,SIG_IGN);
- signal(SIGCHLD,SIG_IGN);
-}
-
-void SignalHandler::shutdown() { shutdownHandler(0); }
-
-void SignalHandler::shutdownHandler(int) {
- sys::Mutex::ScopedLock l(brokerLock);
- if (broker) {
- broker->shutdown();
- broker = 0;
- }
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/SignalHandler.h b/cpp/src/qpid/broker/SignalHandler.h
deleted file mode 100644
index 7bfa9ea630..0000000000
--- a/cpp/src/qpid/broker/SignalHandler.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef QPID_BROKER_SIGNALHANDLER_H
-#define QPID_BROKER_SIGNALHANDLER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-
-/**
- * Handle signals e.g. to shut-down a broker.
- */
-class SignalHandler
-{
- public:
- /** Set the broker to be shutdown on signals.
- * Must be reset by calling setBroker(0) before the broker is deleted.
- */
- static void setBroker(Broker* broker);
-
- /** Initiate shut-down of broker */
- static void shutdown();
-
- private:
- static void shutdownHandler(int);
- static Broker* broker;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_SIGNALHANDLER_H*/
diff --git a/cpp/src/qpid/broker/StatefulQueueObserver.h b/cpp/src/qpid/broker/StatefulQueueObserver.h
deleted file mode 100644
index c682d460b7..0000000000
--- a/cpp/src/qpid/broker/StatefulQueueObserver.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef QPID_BROKER_STATEFULQUEUEOBSERVER_H
-#define QPID_BROKER_STATEFULQUEUEOBSERVER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/QueueObserver.h"
-#include "qpid/framing/FieldTable.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Specialized type of QueueObserver that maintains internal state that has to
- * be replicated across clustered brokers.
- */
-class StatefulQueueObserver : public QueueObserver
-{
- public:
- StatefulQueueObserver(std::string _id) : id(_id) {}
- virtual ~StatefulQueueObserver() {}
-
- /** This identifier must uniquely identify this particular observer amoung
- * all observers on a queue. For cluster replication, this id will be used
- * to identify the peer queue observer for synchronization across
- * brokers.
- */
- const std::string& getId() const { return id; }
-
- /** This method should return the observer's internal state as an opaque
- * map.
- */
- virtual void getState(qpid::framing::FieldTable& state ) const = 0;
-
- /** The input map represents the internal state of the peer observer that
- * this observer should synchonize to.
- */
- virtual void setState(const qpid::framing::FieldTable&) = 0;
-
-
- private:
- std::string id;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_STATEFULQUEUEOBSERVER_H*/
diff --git a/cpp/src/qpid/broker/System.cpp b/cpp/src/qpid/broker/System.cpp
deleted file mode 100644
index 8cd2edda76..0000000000
--- a/cpp/src/qpid/broker/System.cpp
+++ /dev/null
@@ -1,84 +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.
-//
-
-#include "qpid/broker/System.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/framing/Uuid.h"
-#include "qpid/sys/SystemInfo.h"
-#include "qpid/types/Uuid.h"
-#include <iostream>
-#include <fstream>
-
-using qpid::management::ManagementAgent;
-using namespace qpid::broker;
-using namespace std;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-System::System (string _dataDir, Broker* broker) : mgmtObject(0)
-{
- ManagementAgent* agent = broker ? broker->getManagementAgent() : 0;
-
- if (agent != 0)
- {
- framing::Uuid systemId;
-
- if (_dataDir.empty ())
- {
- systemId.generate ();
- }
- else
- {
- string filename (_dataDir + "/systemId");
- ifstream inFile (filename.c_str ());
-
- if (inFile.good ())
- {
- inFile >> systemId;
- inFile.close ();
- }
- else
- {
- systemId.generate ();
- ofstream outFile (filename.c_str ());
- if (outFile.good ())
- {
- outFile << systemId << endl;
- outFile.close ();
- }
- }
- }
-
- mgmtObject = new _qmf::System(agent, this, types::Uuid(systemId.c_array()));
- std::string sysname, nodename, release, version, machine;
- qpid::sys::SystemInfo::getSystemId (sysname,
- nodename,
- release,
- version,
- machine);
- mgmtObject->set_osName (sysname);
- mgmtObject->set_nodeName (nodename);
- mgmtObject->set_release (release);
- mgmtObject->set_version (version);
- mgmtObject->set_machine (machine);
-
- agent->addObject(mgmtObject, 0, true);
- }
-}
-
diff --git a/cpp/src/qpid/broker/System.h b/cpp/src/qpid/broker/System.h
deleted file mode 100644
index 0fc2c2bd88..0000000000
--- a/cpp/src/qpid/broker/System.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _BrokerSystem_
-#define _BrokerSystem_
-
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-#include "qpid/management/Manageable.h"
-#include "qmf/org/apache/qpid/broker/System.h"
-#include <boost/shared_ptr.hpp>
-#include <string>
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-
-class System : public management::Manageable
-{
- private:
-
- qmf::org::apache::qpid::broker::System* mgmtObject;
-
- public:
-
- typedef boost::shared_ptr<System> shared_ptr;
-
- System (std::string _dataDir, Broker* broker = 0);
-
- management::ManagementObject* GetManagementObject (void) const
- { return mgmtObject; }
-};
-
-}}
-
-#endif /*!_BrokerSystem_*/
diff --git a/cpp/src/qpid/broker/ThresholdAlerts.cpp b/cpp/src/qpid/broker/ThresholdAlerts.cpp
deleted file mode 100644
index 3c9e210d4d..0000000000
--- a/cpp/src/qpid/broker/ThresholdAlerts.cpp
+++ /dev/null
@@ -1,191 +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.
- *
- */
-#include "qpid/broker/ThresholdAlerts.h"
-#include "qpid/broker/Queue.h"
-#include "qpid/broker/QueuedMessage.h"
-#include "qpid/amqp_0_10/Codecs.h"
-#include "qpid/log/Statement.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qmf/org/apache/qpid/broker/EventQueueThresholdExceeded.h"
-
-namespace qpid {
-namespace broker {
-namespace {
-const qmf::org::apache::qpid::broker::EventQueueThresholdExceeded EVENT("dummy", 0, 0);
-bool isQMFv2(const boost::intrusive_ptr<Message> message)
-{
- const qpid::framing::MessageProperties* props = message->getProperties<qpid::framing::MessageProperties>();
- return props && props->getAppId() == "qmf2";
-}
-
-bool isThresholdEvent(const boost::intrusive_ptr<Message> message)
-{
- if (message->getIsManagementMessage()) {
- //is this a qmf event? if so is it a threshold event?
- if (isQMFv2(message)) {
- const qpid::framing::FieldTable* headers = message->getApplicationHeaders();
- if (headers && headers->getAsString("qmf.content") == "_event") {
- //decode as list
- std::string content = message->getFrames().getContent();
- qpid::types::Variant::List list;
- qpid::amqp_0_10::ListCodec::decode(content, list);
- if (list.empty() || list.front().getType() != qpid::types::VAR_MAP) return false;
- qpid::types::Variant::Map map = list.front().asMap();
- try {
- std::string eventName = map["_schema_id"].asMap()["_class_name"].asString();
- return eventName == EVENT.getEventName();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Error checking for recursive threshold alert: " << e.what());
- }
- }
- } else {
- std::string content = message->getFrames().getContent();
- qpid::framing::Buffer buffer(const_cast<char*>(content.data()), content.size());
- if (buffer.getOctet() == 'A' && buffer.getOctet() == 'M' && buffer.getOctet() == '2' && buffer.getOctet() == 'e') {
- buffer.getLong();//sequence
- std::string packageName;
- buffer.getShortString(packageName);
- if (packageName != EVENT.getPackageName()) return false;
- std::string eventName;
- buffer.getShortString(eventName);
- return eventName == EVENT.getEventName();
- }
- }
- }
- return false;
-}
-}
-
-ThresholdAlerts::ThresholdAlerts(const std::string& n,
- qpid::management::ManagementAgent& a,
- const uint32_t ct,
- const uint64_t st,
- const long repeat)
- : name(n), agent(a), countThreshold(ct), sizeThreshold(st),
- repeatInterval(repeat ? repeat*qpid::sys::TIME_SEC : 0),
- count(0), size(0), lastAlert(qpid::sys::EPOCH) {}
-
-void ThresholdAlerts::enqueued(const QueuedMessage& m)
-{
- size += m.payload->contentSize();
- ++count;
- if ((countThreshold && count >= countThreshold) || (sizeThreshold && size >= sizeThreshold)) {
- if ((repeatInterval == 0 && lastAlert == qpid::sys::EPOCH)
- || qpid::sys::Duration(lastAlert, qpid::sys::now()) > repeatInterval) {
- //Note: Raising an event may result in messages being
- //enqueued on queues; it may even be that this event
- //causes a message to be enqueued on the queue we are
- //tracking, and so we need to avoid recursing
- if (isThresholdEvent(m.payload)) return;
- lastAlert = qpid::sys::now();
- agent.raiseEvent(qmf::org::apache::qpid::broker::EventQueueThresholdExceeded(name, count, size));
- QPID_LOG(info, "Threshold event triggered for " << name << ", count=" << count << ", size=" << size);
- }
- }
-}
-
-void ThresholdAlerts::dequeued(const QueuedMessage& m)
-{
- size -= m.payload->contentSize();
- --count;
- if ((countThreshold && count < countThreshold) || (sizeThreshold && size < sizeThreshold)) {
- lastAlert = qpid::sys::EPOCH;
- }
-}
-
-
-
-void ThresholdAlerts::observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const uint64_t countThreshold,
- const uint64_t sizeThreshold,
- const long repeatInterval)
-{
- if (countThreshold || sizeThreshold) {
- boost::shared_ptr<QueueObserver> observer(
- new ThresholdAlerts(queue.getName(), agent, countThreshold, sizeThreshold, repeatInterval)
- );
- queue.addObserver(observer);
- }
-}
-
-void ThresholdAlerts::observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::framing::FieldTable& settings, uint16_t limitRatio)
-
-{
- qpid::types::Variant::Map map;
- qpid::amqp_0_10::translate(settings, map);
- observe(queue, agent, map, limitRatio);
-}
-
-template <class T>
-class Option
-{
- public:
- Option(const std::string& name, T d) : defaultValue(d) { names.push_back(name); }
- void addAlias(const std::string& name) { names.push_back(name); }
- T get(const qpid::types::Variant::Map& settings) const
- {
- T value(defaultValue);
- for (std::vector<std::string>::const_iterator i = names.begin(); i != names.end(); ++i) {
- if (get(settings, *i, value)) break;
- }
- return value;
- }
- private:
- std::vector<std::string> names;
- T defaultValue;
-
- bool get(const qpid::types::Variant::Map& settings, const std::string& name, T& value) const
- {
- qpid::types::Variant::Map::const_iterator i = settings.find(name);
- if (i != settings.end()) {
- try {
- value = (T) i->second;
- } catch (const qpid::types::InvalidConversion&) {
- QPID_LOG(warning, "Bad value for" << name << ": " << i->second);
- }
- return true;
- } else {
- return false;
- }
- }
-};
-
-void ThresholdAlerts::observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::types::Variant::Map& settings, uint16_t limitRatio)
-
-{
- //Note: aliases are keys defined by java broker
- Option<int64_t> repeatInterval("qpid.alert_repeat_gap", 60);
- repeatInterval.addAlias("x-qpid-minimum-alert-repeat-gap");
-
- //If no explicit threshold settings were given use specified
- //percentage of any limit from the policy.
- const QueuePolicy* policy = queue.getPolicy();
- Option<uint32_t> countThreshold("qpid.alert_count", (uint32_t) (policy && limitRatio ? (policy->getMaxCount()*limitRatio/100) : 0));
- countThreshold.addAlias("x-qpid-maximum-message-count");
- Option<uint64_t> sizeThreshold("qpid.alert_size", (uint64_t) (policy && limitRatio ? (policy->getMaxSize()*limitRatio/100) : 0));
- sizeThreshold.addAlias("x-qpid-maximum-message-size");
-
- observe(queue, agent, countThreshold.get(settings), sizeThreshold.get(settings), repeatInterval.get(settings));
-}
-
-}}
diff --git a/cpp/src/qpid/broker/ThresholdAlerts.h b/cpp/src/qpid/broker/ThresholdAlerts.h
deleted file mode 100644
index c77722e700..0000000000
--- a/cpp/src/qpid/broker/ThresholdAlerts.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef QPID_BROKER_THRESHOLDALERTS_H
-#define QPID_BROKER_THRESHOLDALERTS_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/QueueObserver.h"
-#include "qpid/sys/Time.h"
-#include "qpid/types/Variant.h"
-#include <string>
-
-namespace qpid {
-namespace framing {
-class FieldTable;
-}
-namespace management {
-class ManagementAgent;
-}
-namespace broker {
-
-class Queue;
-/**
- * Class to manage generation of QMF alerts when particular thresholds
- * are breached on a queue.
- */
-class ThresholdAlerts : public QueueObserver
-{
- public:
- ThresholdAlerts(const std::string& name,
- qpid::management::ManagementAgent& agent,
- const uint32_t countThreshold,
- const uint64_t sizeThreshold,
- const long repeatInterval);
- void enqueued(const QueuedMessage&);
- void dequeued(const QueuedMessage&);
- static void observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const uint64_t countThreshold,
- const uint64_t sizeThreshold,
- const long repeatInterval);
- static void observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::framing::FieldTable& settings, uint16_t limitRatio);
- static void observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::types::Variant::Map& settings, uint16_t limitRatio);
- private:
- const std::string name;
- qpid::management::ManagementAgent& agent;
- const uint32_t countThreshold;
- const uint64_t sizeThreshold;
- const qpid::sys::Duration repeatInterval;
- uint64_t count;
- uint64_t size;
- qpid::sys::AbsTime lastAlert;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_THRESHOLDALERTS_H*/
diff --git a/cpp/src/qpid/broker/TopicExchange.cpp b/cpp/src/qpid/broker/TopicExchange.cpp
deleted file mode 100644
index 644a3d628e..0000000000
--- a/cpp/src/qpid/broker/TopicExchange.cpp
+++ /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.
- *
- */
-#include "qpid/broker/TopicExchange.h"
-#include "qpid/broker/FedOps.h"
-#include "qpid/log/Statement.h"
-#include <algorithm>
-
-
-namespace qpid {
-namespace broker {
-
-using namespace qpid::framing;
-using namespace qpid::sys;
-using namespace std;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-
-// TODO aconway 2006-09-20: More efficient matching algorithm.
-// Areas for improvement:
-// - excessive string copying: should be 0 copy, match from original buffer.
-// - match/lookup: use descision tree or other more efficient structure.
-
-namespace
-{
-const std::string STAR("*");
-const std::string HASH("#");
-}
-
-// iterator for federation ReOrigin bind operation
-class TopicExchange::ReOriginIter : public TopicExchange::BindingNode::TreeIterator {
-public:
- ReOriginIter() {};
- ~ReOriginIter() {};
- bool visit(BindingNode& node) {
- if (node.bindings.fedBinding.hasLocal()) {
- keys2prop.push_back(node.routePattern);
- }
- return true;
- }
- std::vector<std::string> keys2prop;
-};
-
-
-// match iterator used by route(): builds BindingList of all unique queues
-// that match the routing key.
-class TopicExchange::BindingsFinderIter : public TopicExchange::BindingNode::TreeIterator {
-public:
- BindingsFinderIter(BindingList &bl) : b(bl) {};
- ~BindingsFinderIter() {};
-
- BindingList& b;
- std::set<std::string> qSet;
-
- bool visit(BindingNode& node) {
-
- Binding::vector& qv(node.bindings.bindingVector);
- for (Binding::vector::iterator j = qv.begin(); j != qv.end(); j++) {
- // do not duplicate queues on the binding list
- if (qSet.insert(j->get()->queue->getName()).second) {
- b->push_back(*j);
- }
- }
- return true;
- }
-};
-
-
-
-// Iterator to visit all bindings until a given queue is found
-class TopicExchange::QueueFinderIter : public TopicExchange::BindingNode::TreeIterator {
-public:
- QueueFinderIter(Queue::shared_ptr queue) : queue(queue), found(false) {};
- ~QueueFinderIter() {};
- bool visit(BindingNode& node) {
-
- Binding::vector& qv(node.bindings.bindingVector);
- Binding::vector::iterator q;
- for (q = qv.begin(); q != qv.end(); q++) {
- if ((*q)->queue == queue) {
- found = true;
- return false; // search done
- }
- }
- return true; // continue search
- }
-
- Queue::shared_ptr queue;
- bool found;
-};
-
-
-// Iterate over a string of '.'-separated tokens.
-struct TopicExchange::TokenIterator {
- typedef pair<const char*,const char*> Token;
-
- TokenIterator(const char* b, const char* e) : end(e), token(make_pair(b, find(b,e,'.'))) {}
-
- TokenIterator(const string& key) : end(&key[0]+key.size()), token(make_pair(&key[0], find(&key[0],end,'.'))) {}
-
- bool finished() const { return !token.first; }
-
- void next() {
- if (token.second == end)
- token.first = token.second = 0;
- else {
- token.first=token.second+1;
- token.second=(find(token.first, end, '.'));
- }
- }
-
- void pop(string &top) {
- ptrdiff_t l = len();
- if (l) {
- top.assign(token.first, l);
- } else top.clear();
- next();
- }
-
- bool match1(char c) const {
- return token.second==token.first+1 && *token.first == c;
- }
-
- bool match(const Token& token2) const {
- ptrdiff_t l=len();
- return l == token2.second-token2.first &&
- strncmp(token.first, token2.first, l) == 0;
- }
-
- bool match(const string& str) const {
- ptrdiff_t l=len();
- return l == ptrdiff_t(str.size()) &&
- str.compare(0, l, token.first, l) == 0;
- }
-
- ptrdiff_t len() const { return token.second - token.first; }
-
-
- const char* end;
- Token token;
-};
-
-
-class TopicExchange::Normalizer : public TopicExchange::TokenIterator {
- public:
- Normalizer(string& p)
- : TokenIterator(&p[0], &p[0]+p.size()), pattern(p)
- { normalize(); }
-
- private:
- // Apply 2 transformations: #.* -> *.# and #.# -> #
- void normalize() {
- while (!finished()) {
- if (match1('#')) {
- const char* hash1=token.first;
- next();
- if (!finished()) {
- if (match1('#')) { // Erase #.# -> #
- pattern.erase(hash1-pattern.data(), 2);
- token.first -= 2;
- token.second -= 2;
- end -= 2;
- }
- else if (match1('*')) { // Swap #.* -> *.#
- swap(*const_cast<char*>(hash1),
- *const_cast<char*>(token.first));
- }
- }
- }
- else
- next();
- }
- }
-
- string& pattern;
-};
-
-
-
-// Convert sequences of * and # to a sequence of * followed by a single #
-string TopicExchange::normalize(const string& pattern) {
- string normal(pattern);
- Normalizer n(normal);
- return normal;
-}
-
-
-TopicExchange::TopicExchange(const string& _name, Manageable* _parent, Broker* b)
- : Exchange(_name, _parent, b),
- nBindings(0)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type (typeName);
-}
-
-TopicExchange::TopicExchange(const std::string& _name, bool _durable,
- const FieldTable& _args, Manageable* _parent, Broker* b) :
- Exchange(_name, _durable, _args, _parent, b),
- nBindings(0)
-{
- if (mgmtExchange != 0)
- mgmtExchange->set_type (typeName);
-}
-
-bool TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args)
-{
- ClearCache cc(&cacheLock,&bindingCache); // clear the cache on function exit.
- string fedOp(args ? args->getAsString(qpidFedOp) : fedOpBind);
- string fedTags(args ? args->getAsString(qpidFedTags) : "");
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- bool propagate = false;
- string routingPattern = normalize(routingKey);
-
- if (args == 0 || fedOp.empty() || fedOp == fedOpBind) {
- RWlock::ScopedWlock l(lock);
- BindingKey *bk = bindingTree.addBindingKey(routingPattern);
- if (bk) {
- Binding::vector& qv(bk->bindingVector);
- Binding::vector::iterator q;
- for (q = qv.begin(); q != qv.end(); q++) {
- if ((*q)->queue == queue) {
- // already bound, but may be from a different fedOrigin
- bk->fedBinding.addOrigin(queue->getName(), fedOrigin);
- return false;
- }
- }
-
- Binding::shared_ptr binding (new Binding (routingPattern, queue, this, FieldTable(), fedOrigin));
- binding->startManagement();
- bk->bindingVector.push_back(binding);
- nBindings++;
- propagate = bk->fedBinding.addOrigin(queue->getName(), fedOrigin);
- if (mgmtExchange != 0) {
- mgmtExchange->inc_bindingCount();
- }
- QPID_LOG(debug, "Binding key [" << routingPattern << "] to queue " << queue->getName()
- << " on exchange " << getName() << " (origin=" << fedOrigin << ")");
- }
- } else if (fedOp == fedOpUnbind) {
- RWlock::ScopedWlock l(lock);
- BindingKey* bk = getQueueBinding(queue, routingPattern);
- if (bk) {
- QPID_LOG(debug, "FedOpUnbind [" << routingPattern << "] from exchange " << getName()
- << " on queue=" << queue->getName() << " origin=" << fedOrigin);
- propagate = bk->fedBinding.delOrigin(queue->getName(), fedOrigin);
- // if this was the last binding for the queue, delete the binding
- if (bk->fedBinding.countFedBindings(queue->getName()) == 0) {
- deleteBinding(queue, routingPattern, bk);
- }
- }
- } else if (fedOp == fedOpReorigin) {
- /** gather up all the keys that need rebinding in a local vector
- * while holding the lock. Then propagate once the lock is
- * released
- */
- ReOriginIter reOriginIter;
- {
- RWlock::ScopedRlock l(lock);
- bindingTree.iterateAll( reOriginIter );
- } /* lock dropped */
-
- for (std::vector<std::string>::const_iterator key = reOriginIter.keys2prop.begin();
- key != reOriginIter.keys2prop.end(); key++) {
- propagateFedOp( *key, string(), fedOpBind, string());
- }
- }
-
- cc.clearCache(); // clear the cache before we IVE route.
- routeIVE();
- if (propagate)
- propagateFedOp(routingKey, fedTags, fedOp, fedOrigin);
- return true;
-}
-
-bool TopicExchange::unbind(Queue::shared_ptr queue, const string& constRoutingKey, const FieldTable* args)
-{
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- QPID_LOG(debug, "Unbinding key [" << constRoutingKey << "] from queue " << queue->getName()
- << " on exchange " << getName() << " origin=" << fedOrigin << ")" );
-
- ClearCache cc(&cacheLock,&bindingCache); // clear the cache on function exit.
- RWlock::ScopedWlock l(lock);
- string routingKey = normalize(constRoutingKey);
- BindingKey* bk = getQueueBinding(queue, routingKey);
- if (!bk) return false;
- bool propagate = bk->fedBinding.delOrigin(queue->getName(), fedOrigin);
- deleteBinding(queue, routingKey, bk);
- if (propagate)
- propagateFedOp(routingKey, string(), fedOpUnbind, string());
- return true;
-}
-
-
-bool TopicExchange::deleteBinding(Queue::shared_ptr queue,
- const std::string& routingKey,
- BindingKey *bk)
-{
- // Note well: write lock held by caller
- Binding::vector& qv(bk->bindingVector);
- Binding::vector::iterator q;
- for (q = qv.begin(); q != qv.end(); q++)
- if ((*q)->queue == queue)
- break;
- if(q == qv.end()) return false;
- qv.erase(q);
- assert(nBindings > 0);
- nBindings--;
-
- if(qv.empty()) {
- bindingTree.removeBindingKey(routingKey);
- }
- if (mgmtExchange != 0) {
- mgmtExchange->dec_bindingCount();
- }
- QPID_LOG(debug, "Unbound key [" << routingKey << "] from queue " << queue->getName()
- << " on exchange " << getName());
- return true;
-}
-
-/** returns a pointer to the BindingKey if the given queue is bound to this
- * exchange using the routing pattern. 0 if queue binding does not exist.
- */
-TopicExchange::BindingKey *TopicExchange::getQueueBinding(Queue::shared_ptr queue, const string& pattern)
-{
- // Note well: lock held by caller....
- BindingKey *bk = bindingTree.getBindingKey(pattern); // Exact match against binding pattern
- if (!bk) return 0;
- Binding::vector& qv(bk->bindingVector);
- Binding::vector::iterator q;
- for (q = qv.begin(); q != qv.end(); q++)
- if ((*q)->queue == queue)
- break;
- return (q != qv.end()) ? bk : 0;
-}
-
-void TopicExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/)
-{
- // Note: PERFORMANCE CRITICAL!!!
- BindingList b;
- std::map<std::string, BindingList>::iterator it;
- { // only lock the cache for read
- RWlock::ScopedRlock cl(cacheLock);
- it = bindingCache.find(routingKey);
- if (it != bindingCache.end()) {
- b = it->second;
- }
- }
- PreRoute pr(msg, this);
- if (!b.get()) // no cache hit
- {
- RWlock::ScopedRlock l(lock);
- b = BindingList(new std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> >);
- BindingsFinderIter bindingsFinder(b);
- bindingTree.iterateMatch(routingKey, bindingsFinder);
- RWlock::ScopedWlock cwl(cacheLock);
- bindingCache[routingKey] = b; // update cache
- }
- doRoute(msg, b);
-}
-
-bool TopicExchange::isBound(Queue::shared_ptr queue, const string* const routingKey, const FieldTable* const)
-{
- RWlock::ScopedRlock l(lock);
- if (routingKey && queue) {
- string key(normalize(*routingKey));
- return getQueueBinding(queue, key) != 0;
- } else if (!routingKey && !queue) {
- return nBindings > 0;
- } else if (routingKey) {
- if (bindingTree.getBindingKey(*routingKey)) {
- return true;
- }
- } else {
- QueueFinderIter queueFinder(queue);
- bindingTree.iterateAll( queueFinder );
- return queueFinder.found;
- }
- return false;
-}
-
-TopicExchange::~TopicExchange() {}
-
-const std::string TopicExchange::typeName("topic");
-
-//
-// class BindingNode
-//
-
-TopicExchange::BindingNode::~BindingNode()
-{
- childTokens.clear();
-}
-
-
-// Add a binding pattern to the tree. Return a pointer to the binding key
-// of the node that matches the binding pattern.
-TopicExchange::BindingKey*
-TopicExchange::BindingNode::addBindingKey(const std::string& normalizedRoute)
-{
- TokenIterator bKey(normalizedRoute);
- return addBindingKey(bKey, normalizedRoute);
-}
-
-
-// Return a pointer to the binding key of the leaf node that matches the binding pattern.
-TopicExchange::BindingKey*
-TopicExchange::BindingNode::getBindingKey(const std::string& normalizedRoute)
-{
- TokenIterator bKey(normalizedRoute);
- return getBindingKey(bKey);
-}
-
-
-// Delete the binding associated with the given route.
-void TopicExchange::BindingNode::removeBindingKey(const std::string& normalizedRoute)
-{
- TokenIterator bKey2(normalizedRoute);
- removeBindingKey(bKey2, normalizedRoute);
-}
-
-// visit each node in the tree. Note: all nodes are visited,
-// even non-leaf nodes (i.e. nodes without any bindings)
-bool TopicExchange::BindingNode::iterateAll(TopicExchange::BindingNode::TreeIterator& iter)
-{
- if (!iter.visit(*this)) return false;
-
- if (starChild && !starChild->iterateAll(iter)) return false;
-
- if (hashChild && !hashChild->iterateAll(iter)) return false;
-
- for (ChildMap::iterator ptr = childTokens.begin();
- ptr != childTokens.end(); ptr++) {
-
- if (!ptr->second->iterateAll(iter)) return false;
- }
-
- return true;
-}
-
-// applies iter against only matching nodes until iter returns false
-// Note Well: the iter may match against the same node more than once
-// if # wildcards are present!
-bool TopicExchange::BindingNode::iterateMatch(const std::string& routingKey, TreeIterator& iter)
-{
- TopicExchange::TokenIterator rKey(routingKey);
- return iterateMatch( rKey, iter );
-}
-
-
-// recurse over binding using token iterator.
-// Note well: bkey is modified!
-TopicExchange::BindingKey*
-TopicExchange::BindingNode::addBindingKey(TokenIterator &bKey,
- const string& fullPattern)
-{
- if (bKey.finished()) {
- // this node's binding
- if (routePattern.empty()) {
- routePattern = fullPattern;
- } else assert(routePattern == fullPattern);
-
- return &bindings;
-
- } else {
- // pop the topmost token & recurse...
-
- if (bKey.match(STAR)) {
- if (!starChild) {
- starChild.reset(new StarNode());
- }
- bKey.next();
- return starChild->addBindingKey(bKey, fullPattern);
-
- } else if (bKey.match(HASH)) {
- if (!hashChild) {
- hashChild.reset(new HashNode());
- }
- bKey.next();
- return hashChild->addBindingKey(bKey, fullPattern);
-
- } else {
- ChildMap::iterator ptr;
- std::string next_token;
- bKey.pop(next_token);
- ptr = childTokens.find(next_token);
- if (ptr != childTokens.end()) {
- return ptr->second->addBindingKey(bKey, fullPattern);
- } else {
- BindingNode::shared_ptr child(new BindingNode(next_token));
- childTokens[next_token] = child;
- return child->addBindingKey(bKey, fullPattern);
- }
- }
- }
-}
-
-
-// Remove a binding pattern from the tree. Return true if the current
-// node becomes a leaf without any bindings (therefore can be deleted).
-// Note Well: modifies parameter bKey's value!
-bool
-TopicExchange::BindingNode::removeBindingKey(TokenIterator &bKey,
- const string& fullPattern)
-{
- bool remove;
-
- if (!bKey.finished()) {
-
- if (bKey.match(STAR)) {
- bKey.next();
- if (starChild) {
- remove = starChild->removeBindingKey(bKey, fullPattern);
- if (remove) {
- starChild.reset();
- }
- }
- } else if (bKey.match(HASH)) {
- bKey.next();
- if (hashChild) {
- remove = hashChild->removeBindingKey(bKey, fullPattern);
- if (remove) {
- hashChild.reset();
- }
- }
- } else {
- ChildMap::iterator ptr;
- std::string next_token;
- bKey.pop(next_token);
- ptr = childTokens.find(next_token);
- if (ptr != childTokens.end()) {
- remove = ptr->second->removeBindingKey(bKey, fullPattern);
- if (remove) {
- childTokens.erase(ptr);
- }
- }
- }
- }
-
- // no bindings and no children == parent can delete this node.
- return getChildCount() == 0 && bindings.bindingVector.empty();
-}
-
-
-// find the binding key that matches the given binding pattern.
-// Note Well: modifies key parameter!
-TopicExchange::BindingKey*
-TopicExchange::BindingNode::getBindingKey(TokenIterator &key)
-{
- if (key.finished()) {
- return &bindings;
- }
-
- string next_token;
-
- key.pop(next_token);
-
- if (next_token == STAR) {
- if (starChild)
- return starChild->getBindingKey(key);
- } else if (next_token == HASH) {
- if (hashChild)
- return hashChild->getBindingKey(key);
- } else {
- ChildMap::iterator ptr;
- ptr = childTokens.find(next_token);
- if (ptr != childTokens.end()) {
- return ptr->second->getBindingKey(key);
- }
- }
-
- return 0;
-}
-
-
-
-// iterate over all nodes that match the given key. Note well: the set of nodes
-// that are visited includes matching non-leaf nodes.
-// Note well: parameter key is modified!
-bool TopicExchange::BindingNode::iterateMatch(TokenIterator& key, TreeIterator& iter)
-{
- // invariant: key has matched all previous tokens up to this node.
- if (key.finished()) {
- // exact match this node: visit if bound
- if (!bindings.bindingVector.empty())
- if (!iter.visit(*this)) return false;
- }
-
- // check remaining key against children, even if empty.
- return iterateMatchChildren(key, iter);
-}
-
-
-TopicExchange::StarNode::StarNode()
- : BindingNode(STAR) {}
-
-
-// See iterateMatch() above.
-// Special case: this node must verify a token is available (match exactly one).
-bool TopicExchange::StarNode::iterateMatch(TokenIterator& key, TreeIterator& iter)
-{
- // must match one token:
- if (key.finished())
- return true; // match failed, but continue iteration on siblings
-
- // pop the topmost token
- key.next();
-
- if (key.finished()) {
- // exact match this node: visit if bound
- if (!bindings.bindingVector.empty())
- if (!iter.visit(*this)) return false;
- }
-
- return iterateMatchChildren(key, iter);
-}
-
-
-TopicExchange::HashNode::HashNode()
- : BindingNode(HASH) {}
-
-
-// See iterateMatch() above.
-// Special case: can match zero or more tokens at the head of the key.
-bool TopicExchange::HashNode::iterateMatch(TokenIterator& key, TreeIterator& iter)
-{
- // consume each token and look for a match on the
- // remaining key.
- while (!key.finished()) {
- if (!iterateMatchChildren(key, iter)) return false;
- key.next();
- }
-
- if (!bindings.bindingVector.empty())
- return iter.visit(*this);
-
- return true;
-}
-
-
-// helper: iterate over current node's matching children
-bool
-TopicExchange::BindingNode::iterateMatchChildren(const TopicExchange::TokenIterator& key,
- TopicExchange::BindingNode::TreeIterator& iter)
-{
- // always try glob - it can match empty keys
- if (hashChild) {
- TokenIterator tmp(key);
- if (!hashChild->iterateMatch(tmp, iter))
- return false;
- }
-
- if (!key.finished()) {
-
- if (starChild) {
- TokenIterator tmp(key);
- if (!starChild->iterateMatch(tmp, iter))
- return false;
- }
-
- if (!childTokens.empty()) {
- TokenIterator newKey(key);
- std::string next_token;
- newKey.pop(next_token);
-
- ChildMap::iterator ptr = childTokens.find(next_token);
- if (ptr != childTokens.end()) {
- return ptr->second->iterateMatch(newKey, iter);
- }
- }
- }
-
- return true;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/TopicExchange.h b/cpp/src/qpid/broker/TopicExchange.h
deleted file mode 100644
index 636918f8a1..0000000000
--- a/cpp/src/qpid/broker/TopicExchange.h
+++ /dev/null
@@ -1,208 +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.
- *
- */
-#ifndef _TopicExchange_
-#define _TopicExchange_
-
-#include <map>
-#include <vector>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Exchange.h"
-#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/broker/Queue.h"
-
-
-namespace qpid {
-namespace broker {
-
-class TopicExchange : public virtual Exchange {
-
- struct TokenIterator;
- class Normalizer;
-
- struct BindingKey { // binding for this node
- Binding::vector bindingVector;
- FedBinding fedBinding;
- };
-
- // Binding database:
- // The dotted form of a binding key is broken up and stored in a directed tree graph.
- // Common binding prefix are merged. This allows the route match alogrithm to quickly
- // isolate those sub-trees that match a given routingKey.
- // For example, given the routes:
- // a.b.c.<...>
- // a.b.d.<...>
- // a.x.y.<...>
- // The resulting tree would be:
- // a-->b-->c-->...
- // | +-->d-->...
- // +-->x-->y-->...
- //
- class QPID_BROKER_CLASS_EXTERN BindingNode {
- public:
-
- typedef boost::shared_ptr<BindingNode> shared_ptr;
-
- // for database transversal (visit a node).
- class TreeIterator {
- public:
- TreeIterator() {};
- virtual ~TreeIterator() {};
- virtual bool visit(BindingNode& node) = 0;
- };
-
- BindingNode() {};
- BindingNode(const std::string& token) : token(token) {};
- QPID_BROKER_EXTERN virtual ~BindingNode();
-
- // add normalizedRoute to tree, return associated BindingKey
- QPID_BROKER_EXTERN BindingKey* addBindingKey(const std::string& normalizedRoute);
-
- // return BindingKey associated with normalizedRoute
- QPID_BROKER_EXTERN BindingKey* getBindingKey(const std::string& normalizedRoute);
-
- // remove BindingKey associated with normalizedRoute
- QPID_BROKER_EXTERN void removeBindingKey(const std::string& normalizedRoute);
-
- // applies iter against each node in tree until iter returns false
- QPID_BROKER_EXTERN bool iterateAll(TreeIterator& iter);
-
- // applies iter against only matching nodes until iter returns false
- QPID_BROKER_EXTERN bool iterateMatch(const std::string& routingKey, TreeIterator& iter);
-
- std::string routePattern; // normalized binding that matches this node
- BindingKey bindings; // for matches against this node
-
- protected:
-
- std::string token; // portion of pattern represented by this node
-
- // children
- typedef std::map<const std::string, BindingNode::shared_ptr> ChildMap;
- ChildMap childTokens;
- BindingNode::shared_ptr starChild; // "*" subtree
- BindingNode::shared_ptr hashChild; // "#" subtree
-
- unsigned int getChildCount() { return childTokens.size() +
- (starChild ? 1 : 0) + (hashChild ? 1 : 0); }
- BindingKey* addBindingKey(TokenIterator& bKey,
- const std::string& fullPattern);
- bool removeBindingKey(TokenIterator& bKey,
- const std::string& fullPattern);
- BindingKey* getBindingKey(TokenIterator& bKey);
- QPID_BROKER_EXTERN virtual bool iterateMatch(TokenIterator& rKey, TreeIterator& iter);
- bool iterateMatchChildren(const TokenIterator& key, TreeIterator& iter);
- };
-
- // Special case: ("*" token) Node in the tree for a match exactly one wildcard
- class StarNode : public BindingNode {
- public:
- StarNode();
- ~StarNode() {};
-
- protected:
- virtual bool iterateMatch(TokenIterator& key, TreeIterator& iter);
- };
-
- // Special case: ("#" token) Node in the tree for a match zero or more
- class HashNode : public BindingNode {
- public:
- HashNode();
- ~HashNode() {};
-
- protected:
- virtual bool iterateMatch(TokenIterator& key, TreeIterator& iter);
- };
-
- BindingNode bindingTree;
- unsigned long nBindings;
- qpid::sys::RWlock lock; // protects bindingTree and nBindings
- qpid::sys::RWlock cacheLock; // protects cache
- std::map<std::string, BindingList> bindingCache; // cache of matched routes.
- class ClearCache {
- private:
- qpid::sys::RWlock* cacheLock;
- std::map<std::string, BindingList>* bindingCache;
- bool cleared;
- public:
- ClearCache(qpid::sys::RWlock* l, std::map<std::string, BindingList>* bc): cacheLock(l),
- bindingCache(bc),cleared(false) {};
- void clearCache() {
- qpid::sys::RWlock::ScopedWlock l(*cacheLock);
- if (!cleared) {
- bindingCache->clear();
- cleared =true;
- }
- };
- ~ClearCache(){
- clearCache();
- };
- };
- BindingKey *getQueueBinding(Queue::shared_ptr queue, const std::string& pattern);
- bool deleteBinding(Queue::shared_ptr queue,
- const std::string& routingKey,
- BindingKey *bk);
-
- class ReOriginIter;
- class BindingsFinderIter;
- class QueueFinderIter;
-
- public:
- static const std::string typeName;
-
- static QPID_BROKER_EXTERN std::string normalize(const std::string& pattern);
-
- QPID_BROKER_EXTERN TopicExchange(const std::string& name,
- management::Manageable* parent = 0, Broker* broker = 0);
- QPID_BROKER_EXTERN TopicExchange(const std::string& _name,
- bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0, Broker* broker = 0);
-
- virtual std::string getType() const { return typeName; }
-
- QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
-
- virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
-
- QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
- const std::string& routingKey,
- const qpid::framing::FieldTable* args);
-
- QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
- const std::string* const routingKey,
- const qpid::framing::FieldTable* const args);
-
- QPID_BROKER_EXTERN virtual ~TopicExchange();
- virtual bool supportsDynamicBinding() { return true; }
-
- class TopicExchangeTester;
- friend class TopicExchangeTester;
-};
-
-
-
-}
-}
-
-#endif
diff --git a/cpp/src/qpid/broker/TransactionalStore.h b/cpp/src/qpid/broker/TransactionalStore.h
deleted file mode 100644
index 2a2bac0c51..0000000000
--- a/cpp/src/qpid/broker/TransactionalStore.h
+++ /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.
- *
- */
-#ifndef _TransactionalStore_
-#define _TransactionalStore_
-
-#include <memory>
-#include <string>
-#include <set>
-
-namespace qpid {
-namespace broker {
-
-struct InvalidTransactionContextException : public std::exception {};
-
-class TransactionContext {
-public:
- virtual ~TransactionContext(){}
-};
-
-class TPCTransactionContext : public TransactionContext {
-public:
- virtual ~TPCTransactionContext(){}
-};
-
-class TransactionalStore {
-public:
- virtual std::auto_ptr<TransactionContext> begin() = 0;
- virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid) = 0;
- virtual void prepare(TPCTransactionContext& txn) = 0;
- virtual void commit(TransactionContext& txn) = 0;
- virtual void abort(TransactionContext& txn) = 0;
-
- virtual void collectPreparedXids(std::set<std::string>& xids) = 0;
-
- virtual ~TransactionalStore(){}
-};
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/TxAccept.cpp b/cpp/src/qpid/broker/TxAccept.cpp
deleted file mode 100644
index 928ac12c10..0000000000
--- a/cpp/src/qpid/broker/TxAccept.cpp
+++ /dev/null
@@ -1,100 +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.
- *
- */
-#include "qpid/broker/TxAccept.h"
-#include "qpid/log/Statement.h"
-
-using std::bind1st;
-using std::bind2nd;
-using std::mem_fun_ref;
-using namespace qpid::broker;
-using qpid::framing::SequenceSet;
-using qpid::framing::SequenceNumber;
-
-TxAccept::RangeOp::RangeOp(const AckRange& r) : range(r) {}
-
-void TxAccept::RangeOp::prepare(TransactionContext* ctxt)
-{
- for_each(range.start, range.end, bind(&DeliveryRecord::dequeue, _1, ctxt));
-}
-
-void TxAccept::RangeOp::commit()
-{
- for_each(range.start, range.end, bind(&DeliveryRecord::committed, _1));
- for_each(range.start, range.end, bind(&DeliveryRecord::setEnded, _1));
-}
-
-TxAccept::RangeOps::RangeOps(DeliveryRecords& u) : unacked(u) {}
-
-void TxAccept::RangeOps::operator()(SequenceNumber start, SequenceNumber end)
-{
- ranges.push_back(RangeOp(DeliveryRecord::findRange(unacked, start, end)));
-}
-
-void TxAccept::RangeOps::prepare(TransactionContext* ctxt)
-{
- std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt));
-}
-
-void TxAccept::RangeOps::commit()
-{
- std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1));
- //now remove if isRedundant():
- if (!ranges.empty()) {
- DeliveryRecords::iterator begin = ranges.front().range.start;
- DeliveryRecords::iterator end = ranges.back().range.end;
- DeliveryRecords::iterator removed = remove_if(begin, end, mem_fun_ref(&DeliveryRecord::isRedundant));
- unacked.erase(removed, end);
- }
-}
-
-TxAccept::TxAccept(const SequenceSet& _acked, DeliveryRecords& _unacked) :
- acked(_acked), unacked(_unacked), ops(unacked)
-{
- //populate the ops
- acked.for_each(ops);
-}
-
-bool TxAccept::prepare(TransactionContext* ctxt) throw()
-{
- try{
- ops.prepare(ctxt);
- return true;
- }catch(const std::exception& e){
- QPID_LOG(error, "Failed to prepare: " << e.what());
- return false;
- }catch(...){
- QPID_LOG(error, "Failed to prepare");
- return false;
- }
-}
-
-void TxAccept::commit() throw()
-{
- try {
- ops.commit();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to commit: " << e.what());
- } catch(...) {
- QPID_LOG(error, "Failed to commit (unknown error)");
- }
-}
-
-void TxAccept::rollback() throw() {}
diff --git a/cpp/src/qpid/broker/TxAccept.h b/cpp/src/qpid/broker/TxAccept.h
deleted file mode 100644
index 314a150176..0000000000
--- a/cpp/src/qpid/broker/TxAccept.h
+++ /dev/null
@@ -1,83 +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.
- *
- */
-#ifndef _TxAccept_
-#define _TxAccept_
-
-#include <algorithm>
-#include <functional>
-#include <list>
-#include "qpid/framing/SequenceSet.h"
-#include "qpid/broker/DeliveryRecord.h"
-#include "qpid/broker/TxOp.h"
-
-namespace qpid {
- namespace broker {
- /**
- * Defines the transactional behaviour for accepts received by
- * a transactional channel.
- */
- class TxAccept : public TxOp {
- struct RangeOp
- {
- AckRange range;
-
- RangeOp(const AckRange& r);
- void prepare(TransactionContext* ctxt);
- void commit();
- };
-
- struct RangeOps
- {
- std::vector<RangeOp> ranges;
- DeliveryRecords& unacked;
-
- RangeOps(DeliveryRecords& u);
-
- void operator()(framing::SequenceNumber start, framing::SequenceNumber end);
- void prepare(TransactionContext* ctxt);
- void commit();
- };
-
- framing::SequenceSet acked;
- DeliveryRecords& unacked;
- RangeOps ops;
-
- public:
- /**
- * @param acked a representation of the accumulation of
- * acks received
- * @param unacked the record of delivered messages
- */
- TxAccept(const framing::SequenceSet& acked, DeliveryRecords& unacked);
- virtual bool prepare(TransactionContext* ctxt) throw();
- virtual void commit() throw();
- virtual void rollback() throw();
- virtual ~TxAccept(){}
- virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
-
- // Used by cluster replication.
- const framing::SequenceSet& getAcked() const { return acked; }
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/TxBuffer.cpp b/cpp/src/qpid/broker/TxBuffer.cpp
deleted file mode 100644
index b509778e89..0000000000
--- a/cpp/src/qpid/broker/TxBuffer.cpp
+++ /dev/null
@@ -1,80 +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.
- *
- */
-#include "qpid/broker/TxBuffer.h"
-#include "qpid/log/Statement.h"
-
-#include <boost/mem_fn.hpp>
-#include <boost/bind.hpp>
-using boost::mem_fn;
-using namespace qpid::broker;
-
-bool TxBuffer::prepare(TransactionContext* const ctxt)
-{
- for(op_iterator i = ops.begin(); i < ops.end(); i++){
- if(!(*i)->prepare(ctxt)){
- return false;
- }
- }
- return true;
-}
-
-void TxBuffer::commit()
-{
- std::for_each(ops.begin(), ops.end(), mem_fn(&TxOp::commit));
- ops.clear();
-}
-
-void TxBuffer::rollback()
-{
- std::for_each(ops.begin(), ops.end(), mem_fn(&TxOp::rollback));
- ops.clear();
-}
-
-void TxBuffer::enlist(TxOp::shared_ptr op)
-{
- ops.push_back(op);
-}
-
-bool TxBuffer::commitLocal(TransactionalStore* const store)
-{
- if (!store) return false;
- try {
- std::auto_ptr<TransactionContext> ctxt = store->begin();
- if (prepare(ctxt.get())) {
- store->commit(*ctxt);
- commit();
- return true;
- } else {
- store->abort(*ctxt);
- rollback();
- return false;
- }
- } catch (std::exception& e) {
- QPID_LOG(error, "Commit failed with exception: " << e.what());
- } catch (...) {
- QPID_LOG(error, "Commit failed with unknown exception");
- }
- return false;
-}
-
-void TxBuffer::accept(TxOpConstVisitor& v) const {
- std::for_each(ops.begin(), ops.end(), boost::bind(&TxOp::accept, _1, boost::ref(v)));
-}
diff --git a/cpp/src/qpid/broker/TxBuffer.h b/cpp/src/qpid/broker/TxBuffer.h
deleted file mode 100644
index d49c8ba16a..0000000000
--- a/cpp/src/qpid/broker/TxBuffer.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#ifndef _TxBuffer_
-#define _TxBuffer_
-
-#include <algorithm>
-#include <functional>
-#include <vector>
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/TransactionalStore.h"
-#include "qpid/broker/TxOp.h"
-
-/**
- * Represents a single transaction. As such, an instance of this class
- * will hold a list of operations representing the workload of the
- * transaction. This work can be committed or rolled back. Committing
- * is a two-stage process: first all the operations should be
- * prepared, then if that succeeds they can be committed.
- *
- * In the 2pc case, a successful prepare may be followed by either a
- * commit or a rollback.
- *
- * Atomicity of prepare is ensured by using a lower level
- * transactional facility. This saves explicitly rolling back all the
- * successfully prepared ops when one of them fails. i.e. we do not
- * use 2pc internally, we instead ensure that prepare is atomic at a
- * lower level. This makes individual prepare operations easier to
- * code.
- *
- * Transactions on a messaging broker effect three types of 'action':
- * (1) updates to persistent storage (2) updates to transient storage
- * or cached data (3) network writes.
- *
- * Of these, (1) should always occur atomically during prepare to
- * ensure that if the broker crashes while a transaction is being
- * completed the persistent state (which is all that then remains) is
- * consistent. (3) can only be done on commit, after a successful
- * prepare. There is a little more flexibility with (2) but any
- * changes made during prepare should be subject to the control of the
- * TransactionalStore in use.
- */
-namespace qpid {
- namespace broker {
- class TxBuffer{
- typedef std::vector<TxOp::shared_ptr>::iterator op_iterator;
- std::vector<TxOp::shared_ptr> ops;
- protected:
-
- public:
- typedef boost::shared_ptr<TxBuffer> shared_ptr;
- /**
- * Adds an operation to the transaction.
- */
- QPID_BROKER_EXTERN void enlist(TxOp::shared_ptr op);
-
- /**
- * Requests that all ops are prepared. This should
- * primarily involve making sure that a persistent record
- * of the operations is stored where necessary.
- *
- * Once prepared, a transaction can be committed (or in
- * the 2pc case, rolled back).
- *
- * @returns true if all the operations prepared
- * successfully, false if not.
- */
- QPID_BROKER_EXTERN bool prepare(TransactionContext* const ctxt);
-
- /**
- * Signals that the ops all prepared successfully and can
- * now commit, i.e. the operation can now be fully carried
- * out.
- *
- * Should only be called after a call to prepare() returns
- * true.
- */
- QPID_BROKER_EXTERN void commit();
-
- /**
- * Signals that all ops can be rolled back.
- *
- * Should only be called either after a call to prepare()
- * returns true (2pc) or instead of a prepare call
- * ('server-local')
- */
- QPID_BROKER_EXTERN void rollback();
-
- /**
- * Helper method for managing the process of server local
- * commit
- */
- QPID_BROKER_EXTERN bool commitLocal(TransactionalStore* const store);
-
- // Used by cluster to replicate transaction status.
- void accept(TxOpConstVisitor& v) const;
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/TxOp.h b/cpp/src/qpid/broker/TxOp.h
deleted file mode 100644
index a8fa1c2621..0000000000
--- a/cpp/src/qpid/broker/TxOp.h
+++ /dev/null
@@ -1,46 +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.
- *
- */
-#ifndef _TxOp_
-#define _TxOp_
-
-#include "qpid/broker/TxOpVisitor.h"
-#include "qpid/broker/TransactionalStore.h"
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
- namespace broker {
-
- class TxOp{
- public:
- typedef boost::shared_ptr<TxOp> shared_ptr;
-
- virtual bool prepare(TransactionContext*) throw() = 0;
- virtual void commit() throw() = 0;
- virtual void rollback() throw() = 0;
- virtual ~TxOp(){}
-
- virtual void accept(TxOpConstVisitor&) const = 0;
- };
-
-}} // namespace qpid::broker
-
-
-#endif
diff --git a/cpp/src/qpid/broker/TxOpVisitor.h b/cpp/src/qpid/broker/TxOpVisitor.h
deleted file mode 100644
index ceb894896e..0000000000
--- a/cpp/src/qpid/broker/TxOpVisitor.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef QPID_BROKER_TXOPVISITOR_H
-#define QPID_BROKER_TXOPVISITOR_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-namespace qpid {
-namespace broker {
-
-class DtxAck;
-class RecoveredDequeue;
-class RecoveredEnqueue;
-class TxAccept;
-class TxPublish;
-
-/**
- * Visitor for TxOp familly of classes.
- */
-struct TxOpConstVisitor
-{
- virtual ~TxOpConstVisitor() {}
- virtual void operator()(const DtxAck&) = 0;
- virtual void operator()(const RecoveredDequeue&) = 0;
- virtual void operator()(const RecoveredEnqueue&) = 0;
- virtual void operator()(const TxAccept&) = 0;
- virtual void operator()(const TxPublish&) = 0;
-};
-
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_TXOPVISITOR_H*/
-#ifndef QPID_BROKER_TXOPVISITOR_H
-#define QPID_BROKER_TXOPVISITOR_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-namespace qpid {
-namespace broker {
-
-class DtxAck;
-class RecoveredDequeue;
-class RecoveredEnqueue;
-class TxAccept;
-class TxPublish;
-
-/**
- * Visitor for TxOp familly of classes.
- */
-struct TxOpConstVisitor
-{
- virtual ~TxOpConstVisitor() {}
- virtual void operator()(const DtxAck&) = 0;
- virtual void operator()(const RecoveredDequeue&) = 0;
- virtual void operator()(const RecoveredEnqueue&) = 0;
- virtual void operator()(const TxAccept&) = 0;
- virtual void operator()(const TxPublish&) = 0;
-};
-
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_TXOPVISITOR_H*/
diff --git a/cpp/src/qpid/broker/TxPublish.cpp b/cpp/src/qpid/broker/TxPublish.cpp
deleted file mode 100644
index 9c2cf4a467..0000000000
--- a/cpp/src/qpid/broker/TxPublish.cpp
+++ /dev/null
@@ -1,111 +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.
- *
- */
-#include "qpid/log/Statement.h"
-#include "qpid/broker/TxPublish.h"
-#include "qpid/broker/Queue.h"
-
-using boost::intrusive_ptr;
-using namespace qpid::broker;
-
-TxPublish::TxPublish(intrusive_ptr<Message> _msg) : msg(_msg) {}
-
-bool TxPublish::prepare(TransactionContext* ctxt) throw()
-{
- try{
- while (!queues.empty()) {
- prepare(ctxt, queues.front());
- prepared.push_back(queues.front());
- queues.pop_front();
- }
- return true;
- }catch(const std::exception& e){
- QPID_LOG(error, "Failed to prepare: " << e.what());
- }catch(...){
- QPID_LOG(error, "Failed to prepare (unknown error)");
- }
- return false;
-}
-
-void TxPublish::commit() throw()
-{
- try {
- for_each(prepared.begin(), prepared.end(), Commit(msg));
- if (msg->isContentReleaseRequested()) {
- // NOTE: The log messages in this section are used for flow-to-disk testing (which checks the log for the
- // presence of these messages). Do not change these without also checking these tests.
- if (msg->isContentReleaseBlocked()) {
- QPID_LOG(debug, "Message id=\"" << msg->getProperties<qpid::framing::MessageProperties>()->getMessageId() << "\"; pid=0x" <<
- std::hex << msg->getPersistenceId() << std::dec << ": Content release blocked on commit");
- } else {
- msg->releaseContent();
- QPID_LOG(debug, "Message id=\"" << msg->getProperties<qpid::framing::MessageProperties>()->getMessageId() << "\"; pid=0x" <<
- std::hex << msg->getPersistenceId() << std::dec << ": Content released on commit");
- }
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to commit: " << e.what());
- } catch(...) {
- QPID_LOG(error, "Failed to commit (unknown error)");
- }
-}
-
-void TxPublish::rollback() throw()
-{
- try {
- for_each(prepared.begin(), prepared.end(), Rollback(msg));
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to complete rollback: " << e.what());
- } catch(...) {
- QPID_LOG(error, "Failed to complete rollback (unknown error)");
- }
-
-}
-
-void TxPublish::deliverTo(const boost::shared_ptr<Queue>& queue){
- if (!queue->isLocal(msg)) {
- queues.push_back(queue);
- delivered = true;
- } else {
- QPID_LOG(debug, "Won't enqueue local message for " << queue->getName());
- }
-}
-
-void TxPublish::prepare(TransactionContext* ctxt, const boost::shared_ptr<Queue> queue)
-{
- queue->enqueue(ctxt, msg);
-}
-
-TxPublish::Commit::Commit(intrusive_ptr<Message>& _msg) : msg(_msg){}
-
-void TxPublish::Commit::operator()(const boost::shared_ptr<Queue>& queue){
- queue->process(msg);
-}
-
-TxPublish::Rollback::Rollback(intrusive_ptr<Message>& _msg) : msg(_msg){}
-
-void TxPublish::Rollback::operator()(const boost::shared_ptr<Queue>& queue){
- queue->enqueueAborted(msg);
-}
-
-uint64_t TxPublish::contentSize ()
-{
- return msg->contentSize ();
-}
diff --git a/cpp/src/qpid/broker/TxPublish.h b/cpp/src/qpid/broker/TxPublish.h
deleted file mode 100644
index f0b9c0a302..0000000000
--- a/cpp/src/qpid/broker/TxPublish.h
+++ /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.
- *
- */
-#ifndef _TxPublish_
-#define _TxPublish_
-
-#include "qpid/broker/BrokerImportExport.h"
-#include "qpid/broker/Deliverable.h"
-#include "qpid/broker/Message.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/broker/TxOp.h"
-
-#include <algorithm>
-#include <functional>
-#include <list>
-
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
- namespace broker {
- /**
- * Defines the behaviour for publish operations on a
- * transactional channel. Messages are routed through
- * exchanges when received but are not at that stage delivered
- * to the matching queues, rather the queues are held in an
- * instance of this class. On prepare() the message is marked
- * enqueued to the relevant queues in the MessagesStore. On
- * commit() the messages will be passed to the queue for
- * dispatch or to be added to the in-memory queue.
- */
- class QPID_BROKER_CLASS_EXTERN TxPublish : public TxOp, public Deliverable{
-
- class Commit{
- boost::intrusive_ptr<Message>& msg;
- public:
- Commit(boost::intrusive_ptr<Message>& msg);
- void operator()(const boost::shared_ptr<Queue>& queue);
- };
- class Rollback{
- boost::intrusive_ptr<Message>& msg;
- public:
- Rollback(boost::intrusive_ptr<Message>& msg);
- void operator()(const boost::shared_ptr<Queue>& queue);
- };
-
- boost::intrusive_ptr<Message> msg;
- std::list<boost::shared_ptr<Queue> > queues;
- std::list<boost::shared_ptr<Queue> > prepared;
-
- void prepare(TransactionContext* ctxt, boost::shared_ptr<Queue>);
-
- public:
- QPID_BROKER_EXTERN TxPublish(boost::intrusive_ptr<Message> msg);
- QPID_BROKER_EXTERN virtual bool prepare(TransactionContext* ctxt) throw();
- QPID_BROKER_EXTERN virtual void commit() throw();
- QPID_BROKER_EXTERN virtual void rollback() throw();
-
- virtual Message& getMessage() { return *msg; };
-
- QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
-
- virtual ~TxPublish(){}
- virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
-
- QPID_BROKER_EXTERN uint64_t contentSize();
-
- boost::intrusive_ptr<Message> getMessage() const { return msg; }
- const std::list<boost::shared_ptr<Queue> > getQueues() const { return queues; }
- };
- }
-}
-
-
-#endif
diff --git a/cpp/src/qpid/broker/Vhost.cpp b/cpp/src/qpid/broker/Vhost.cpp
deleted file mode 100644
index a9ca3b42ab..0000000000
--- a/cpp/src/qpid/broker/Vhost.cpp
+++ /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.
-//
-
-#include "qpid/broker/Vhost.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/management/ManagementAgent.h"
-
-using namespace qpid::broker;
-using qpid::management::ManagementAgent;
-namespace _qmf = qmf::org::apache::qpid::broker;
-
-namespace qpid { namespace management {
-class Manageable;
-}}
-
-Vhost::Vhost (qpid::management::Manageable* parentBroker, Broker* broker) : mgmtObject(0)
-{
- if (parentBroker != 0 && broker != 0)
- {
- ManagementAgent* agent = broker->getManagementAgent();
-
- if (agent != 0)
- {
- mgmtObject = new _qmf::Vhost(agent, this, parentBroker, "/");
- agent->addObject(mgmtObject, 0, true);
- }
- }
-}
-
-void Vhost::setFederationTag(const std::string& tag)
-{
- mgmtObject->set_federationTag(tag);
-}
diff --git a/cpp/src/qpid/broker/Vhost.h b/cpp/src/qpid/broker/Vhost.h
deleted file mode 100644
index 9554d641c2..0000000000
--- a/cpp/src/qpid/broker/Vhost.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _Vhost_
-#define _Vhost_
-
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-#include "qpid/management/Manageable.h"
-#include "qmf/org/apache/qpid/broker/Vhost.h"
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace broker {
-
-class Broker;
-class Vhost : public management::Manageable
-{
- private:
-
- qmf::org::apache::qpid::broker::Vhost* mgmtObject;
-
- public:
-
- typedef boost::shared_ptr<Vhost> shared_ptr;
-
- Vhost (management::Manageable* parentBroker, Broker* broker = 0);
-
- management::ManagementObject* GetManagementObject (void) const
- { return mgmtObject; }
- void setFederationTag(const std::string& tag);
-};
-
-}}
-
-#endif /*!_Vhost_*/
diff --git a/cpp/src/qpid/broker/posix/BrokerDefaults.cpp b/cpp/src/qpid/broker/posix/BrokerDefaults.cpp
deleted file mode 100644
index 9e463fa32d..0000000000
--- a/cpp/src/qpid/broker/posix/BrokerDefaults.cpp
+++ /dev/null
@@ -1,40 +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.
- *
- */
-
-#include "qpid/broker/Broker.h"
-#include <stdlib.h>
-
-namespace qpid {
-namespace broker {
-
-const std::string Broker::Options::DEFAULT_DATA_DIR_LOCATION("/tmp");
-const std::string Broker::Options::DEFAULT_DATA_DIR_NAME("/.qpidd");
-
-std::string
-Broker::Options::getHome() {
- std::string home;
- char *home_c = ::getenv("HOME");
- if (home_c != 0)
- home += home_c;
- return home;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/windows/BrokerDefaults.cpp b/cpp/src/qpid/broker/windows/BrokerDefaults.cpp
deleted file mode 100644
index b65440b5ad..0000000000
--- a/cpp/src/qpid/broker/windows/BrokerDefaults.cpp
+++ /dev/null
@@ -1,47 +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.
- *
- */
-
-#include "qpid/broker/Broker.h"
-#include <stdlib.h>
-
-namespace qpid {
-namespace broker {
-
-const std::string Broker::Options::DEFAULT_DATA_DIR_LOCATION("\\TEMP");
-const std::string Broker::Options::DEFAULT_DATA_DIR_NAME("\\QPIDD.DATA");
-
-std::string
-Broker::Options::getHome() {
- std::string home;
-#ifdef _MSC_VER
- char home_c[MAX_PATH+1];
- size_t unused;
- if (0 == getenv_s (&unused, home_c, sizeof(home_c), "HOME"))
- home += home_c;
-#else
- char *home_c = getenv("HOME");
- if (home_c)
- home += home_c;
-#endif
- return home;
-}
-
-}} // namespace qpid::broker
diff --git a/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp b/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp
deleted file mode 100644
index 962877a471..0000000000
--- a/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-// This source is only used on Windows; SSPI is the Windows mechanism for
-// accessing authentication mechanisms, analogous to Cyrus SASL.
-
-#include "qpid/broker/Connection.h"
-#include "qpid/log/Statement.h"
-#include "qpid/framing/reply_exceptions.h"
-
-#include <windows.h>
-
-using namespace qpid::framing;
-using qpid::sys::SecurityLayer;
-
-namespace qpid {
-namespace broker {
-
-class NullAuthenticator : public SaslAuthenticator
-{
- Connection& connection;
- framing::AMQP_ClientProxy::Connection client;
-public:
- NullAuthenticator(Connection& connection);
- ~NullAuthenticator();
- void getMechanisms(framing::Array& mechanisms);
- void start(const std::string& mechanism, const std::string& response);
- void step(const std::string&) {}
- std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
-};
-
-class SspiAuthenticator : public SaslAuthenticator
-{
- HANDLE userToken;
- Connection& connection;
- framing::AMQP_ClientProxy::Connection client;
-
-public:
- SspiAuthenticator(Connection& connection);
- ~SspiAuthenticator();
- void getMechanisms(framing::Array& mechanisms);
- void start(const std::string& mechanism, const std::string& response);
- void step(const std::string& response);
- std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
-};
-
-bool SaslAuthenticator::available(void)
-{
- return true;
-}
-
-// Initialize the SASL mechanism; throw if it fails.
-void SaslAuthenticator::init(const std::string& /*saslName*/, const std::string& /*saslConfig*/)
-{
- return;
-}
-
-void SaslAuthenticator::fini(void)
-{
- return;
-}
-
-std::auto_ptr<SaslAuthenticator> SaslAuthenticator::createAuthenticator(Connection& c, bool)
-{
- if (c.getBroker().getOptions().auth) {
- return std::auto_ptr<SaslAuthenticator>(new SspiAuthenticator(c));
- } else {
- return std::auto_ptr<SaslAuthenticator>(new NullAuthenticator(c));
- }
-}
-
-NullAuthenticator::NullAuthenticator(Connection& c) : connection(c), client(c.getOutput()) {}
-NullAuthenticator::~NullAuthenticator() {}
-
-void NullAuthenticator::getMechanisms(Array& mechanisms)
-{
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("ANONYMOUS")));
-}
-
-void NullAuthenticator::start(const string& mechanism, const string& response)
-{
- QPID_LOG(warning, "SASL: No Authentication Performed");
- if (mechanism == "PLAIN") { // Old behavior
- if (response.size() > 0 && response[0] == (char) 0) {
- string temp = response.substr(1);
- string::size_type i = temp.find((char)0);
- string uid = temp.substr(0, i);
- string pwd = temp.substr(i + 1);
- connection.setUserId(uid);
- }
- } else {
- connection.setUserId("anonymous");
- }
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, 0);
-}
-
-std::auto_ptr<SecurityLayer> NullAuthenticator::getSecurityLayer(uint16_t)
-{
- std::auto_ptr<SecurityLayer> securityLayer;
- return securityLayer;
-}
-
-
-SspiAuthenticator::SspiAuthenticator(Connection& c) : userToken(INVALID_HANDLE_VALUE), connection(c), client(c.getOutput())
-{
-}
-
-SspiAuthenticator::~SspiAuthenticator()
-{
- if (INVALID_HANDLE_VALUE != userToken) {
- CloseHandle(userToken);
- userToken = INVALID_HANDLE_VALUE;
- }
-}
-
-void SspiAuthenticator::getMechanisms(Array& mechanisms)
-{
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value(string("ANONYMOUS"))));
- mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value(string("PLAIN"))));
- QPID_LOG(info, "SASL: Mechanism list: ANONYMOUS PLAIN");
-}
-
-void SspiAuthenticator::start(const string& mechanism, const string& response)
-{
- QPID_LOG(info, "SASL: Starting authentication with mechanism: " << mechanism);
- if (mechanism == "ANONYMOUS") {
- connection.setUserId("anonymous");
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, 0);
- return;
- }
- if (mechanism != "PLAIN")
- throw ConnectionForcedException("Unsupported mechanism");
-
- // PLAIN's response is composed of 3 strings separated by 0 bytes:
- // authorization id, authentication id (user), clear-text password.
- if (response.size() == 0)
- throw ConnectionForcedException("Authentication failed");
-
- string::size_type i = response.find((char)0);
- string auth = response.substr(0, i);
- string::size_type j = response.find((char)0, i+1);
- string uid = response.substr(i+1, j-1);
- string pwd = response.substr(j+1);
- string dot(".");
- int error = 0;
- if (!LogonUser(const_cast<char*>(uid.c_str()),
- const_cast<char*>(dot.c_str()),
- const_cast<char*>(pwd.c_str()),
- LOGON32_LOGON_NETWORK,
- LOGON32_PROVIDER_DEFAULT,
- &userToken))
- error = GetLastError();
- pwd.replace(0, string::npos, 1, (char)0);
- if (error != 0) {
- QPID_LOG(info,
- "SASL: Auth failed [" << error << "]: " << qpid::sys::strError(error));
- throw ConnectionForcedException("Authentication failed");
- }
-
- connection.setUserId(uid);
- client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, 0);
-}
-
-void SspiAuthenticator::step(const string& /*response*/)
-{
- QPID_LOG(info, "SASL: Need another step!!!");
-}
-
-std::auto_ptr<SecurityLayer> SspiAuthenticator::getSecurityLayer(uint16_t)
-{
- std::auto_ptr<SecurityLayer> securityLayer;
- return securityLayer;
-}
-
-}}
diff --git a/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp b/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
deleted file mode 100644
index fd0e537192..0000000000
--- a/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
+++ /dev/null
@@ -1,302 +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.
- *
- */
-
-#include "qpid/sys/ProtocolFactory.h"
-
-#include "qpid/Plugin.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/AsynchIOHandler.h"
-#include "qpid/sys/ConnectionCodec.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/SystemInfo.h"
-#include "qpid/sys/windows/SslAsynchIO.h"
-#include <boost/bind.hpp>
-#include <memory>
-// security.h needs to see this to distinguish from kernel use.
-#define SECURITY_WIN32
-#include <security.h>
-#include <Schnlsp.h>
-#undef SECURITY_WIN32
-
-
-namespace qpid {
-namespace sys {
-namespace windows {
-
-struct SslServerOptions : qpid::Options
-{
- std::string certStore;
- std::string certName;
- uint16_t port;
- bool clientAuth;
-
- SslServerOptions() : qpid::Options("SSL Options"),
- certStore("My"), port(5671), clientAuth(false)
- {
- qpid::Address me;
- if (qpid::sys::SystemInfo::getLocalHostname(me))
- certName = me.host;
- else
- certName = "localhost";
-
- addOptions()
- ("ssl-cert-store", optValue(certStore, "NAME"), "Local store name from which to obtain certificate")
- ("ssl-cert-name", optValue(certName, "NAME"), "Name of the certificate to use")
- ("ssl-port", optValue(port, "PORT"), "Port on which to listen for SSL connections")
- ("ssl-require-client-authentication", optValue(clientAuth),
- "Forces clients to authenticate in order to establish an SSL connection");
- }
-};
-
-class SslProtocolFactory : public qpid::sys::ProtocolFactory {
- qpid::sys::Socket listener;
- const bool tcpNoDelay;
- const uint16_t listeningPort;
- std::string brokerHost;
- const bool clientAuthSelected;
- std::auto_ptr<qpid::sys::AsynchAcceptor> acceptor;
- ConnectFailedCallback connectFailedCallback;
- CredHandle credHandle;
-
- public:
- SslProtocolFactory(const SslServerOptions&, int backlog, bool nodelay);
- ~SslProtocolFactory();
- void accept(sys::Poller::shared_ptr, sys::ConnectionCodec::Factory*);
- void connect(sys::Poller::shared_ptr, const std::string& host, int16_t port,
- sys::ConnectionCodec::Factory*,
- ConnectFailedCallback failed);
-
- uint16_t getPort() const;
- std::string getHost() const;
- bool supports(const std::string& capability);
-
- private:
- void connectFailed(const qpid::sys::Socket&,
- int err,
- const std::string& msg);
- void established(sys::Poller::shared_ptr,
- const qpid::sys::Socket&,
- sys::ConnectionCodec::Factory*,
- bool isClient);
-};
-
-// Static instance to initialise plugin
-static struct SslPlugin : public Plugin {
- SslServerOptions options;
-
- Options* getOptions() { return &options; }
-
- void earlyInitialize(Target&) {
- }
-
- void initialize(Target& target) {
- broker::Broker* broker = dynamic_cast<broker::Broker*>(&target);
- // Only provide to a Broker
- if (broker) {
- try {
- const broker::Broker::Options& opts = broker->getOptions();
- ProtocolFactory::shared_ptr protocol(new SslProtocolFactory(options,
- opts.connectionBacklog,
- opts.tcpNoDelay));
- QPID_LOG(notice, "Listening for SSL connections on TCP port " << protocol->getPort());
- broker->registerProtocolFactory("ssl", protocol);
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to initialise SSL listener: " << e.what());
- }
- }
- }
-} sslPlugin;
-
-SslProtocolFactory::SslProtocolFactory(const SslServerOptions& options,
- int backlog,
- bool nodelay)
- : tcpNoDelay(nodelay),
- listeningPort(listener.listen(options.port, backlog)),
- clientAuthSelected(options.clientAuth) {
-
- SecInvalidateHandle(&credHandle);
-
- // Get the certificate for this server.
- HCERTSTORE certStoreHandle;
- certStoreHandle = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_A,
- X509_ASN_ENCODING,
- 0,
- CERT_SYSTEM_STORE_LOCAL_MACHINE,
- options.certStore.c_str());
- if (!certStoreHandle)
- throw qpid::Exception(QPID_MSG("Opening store " << options.certStore << " " << qpid::sys::strError(GetLastError())));
-
- PCCERT_CONTEXT certContext;
- certContext = ::CertFindCertificateInStore(certStoreHandle,
- X509_ASN_ENCODING,
- 0,
- CERT_FIND_SUBJECT_STR_A,
- options.certName.c_str(),
- NULL);
- if (certContext == NULL) {
- int err = ::GetLastError();
- ::CertCloseStore(certStoreHandle, 0);
- throw qpid::Exception(QPID_MSG("Locating certificate " << options.certName << " in store " << options.certStore << " " << qpid::sys::strError(GetLastError())));
- throw QPID_WINDOWS_ERROR(err);
- }
-
- SCHANNEL_CRED cred;
- memset(&cred, 0, sizeof(cred));
- cred.dwVersion = SCHANNEL_CRED_VERSION;
- cred.cCreds = 1;
- cred.paCred = &certContext;
- SECURITY_STATUS status = ::AcquireCredentialsHandle(NULL,
- UNISP_NAME,
- SECPKG_CRED_INBOUND,
- NULL,
- &cred,
- NULL,
- NULL,
- &credHandle,
- NULL);
- if (status != SEC_E_OK)
- throw QPID_WINDOWS_ERROR(status);
- ::CertFreeCertificateContext(certContext);
- ::CertCloseStore(certStoreHandle, 0);
-}
-
-SslProtocolFactory::~SslProtocolFactory() {
- ::FreeCredentialsHandle(&credHandle);
-}
-
-void SslProtocolFactory::connectFailed(const qpid::sys::Socket&,
- int err,
- const std::string& msg) {
- if (connectFailedCallback)
- connectFailedCallback(err, msg);
-}
-
-void SslProtocolFactory::established(sys::Poller::shared_ptr poller,
- const qpid::sys::Socket& s,
- sys::ConnectionCodec::Factory* f,
- bool isClient) {
- sys::AsynchIOHandler* async = new sys::AsynchIOHandler(s.getFullAddress(), f);
-
- if (tcpNoDelay) {
- s.setTcpNoDelay();
- QPID_LOG(info,
- "Set TCP_NODELAY on connection to " << s.getPeerAddress());
- }
-
- SslAsynchIO *aio;
- if (isClient) {
- async->setClient();
- aio =
- new qpid::sys::windows::ClientSslAsynchIO(brokerHost,
- s,
- credHandle,
- boost::bind(&AsynchIOHandler::readbuff, async, _1, _2),
- boost::bind(&AsynchIOHandler::eof, async, _1),
- boost::bind(&AsynchIOHandler::disconnect, async, _1),
- boost::bind(&AsynchIOHandler::closedSocket, async, _1, _2),
- boost::bind(&AsynchIOHandler::nobuffs, async, _1),
- boost::bind(&AsynchIOHandler::idle, async, _1));
- }
- else {
- aio =
- new qpid::sys::windows::ServerSslAsynchIO(clientAuthSelected,
- s,
- credHandle,
- boost::bind(&AsynchIOHandler::readbuff, async, _1, _2),
- boost::bind(&AsynchIOHandler::eof, async, _1),
- boost::bind(&AsynchIOHandler::disconnect, async, _1),
- boost::bind(&AsynchIOHandler::closedSocket, async, _1, _2),
- boost::bind(&AsynchIOHandler::nobuffs, async, _1),
- boost::bind(&AsynchIOHandler::idle, async, _1));
- }
-
- async->init(aio, 4);
- aio->start(poller);
-}
-
-uint16_t SslProtocolFactory::getPort() const {
- return listeningPort; // Immutable no need for lock.
-}
-
-std::string SslProtocolFactory::getHost() const {
- return listener.getSockname();
-}
-
-void SslProtocolFactory::accept(sys::Poller::shared_ptr poller,
- sys::ConnectionCodec::Factory* fact) {
- acceptor.reset(
- AsynchAcceptor::create(listener,
- boost::bind(&SslProtocolFactory::established, this, poller, _1, fact, false)));
- acceptor->start(poller);
-}
-
-void SslProtocolFactory::connect(sys::Poller::shared_ptr poller,
- const std::string& host,
- int16_t port,
- sys::ConnectionCodec::Factory* fact,
- ConnectFailedCallback failed)
-{
- SCHANNEL_CRED cred;
- memset(&cred, 0, sizeof(cred));
- cred.dwVersion = SCHANNEL_CRED_VERSION;
- SECURITY_STATUS status = ::AcquireCredentialsHandle(NULL,
- UNISP_NAME,
- SECPKG_CRED_OUTBOUND,
- NULL,
- &cred,
- NULL,
- NULL,
- &credHandle,
- NULL);
- if (status != SEC_E_OK)
- throw QPID_WINDOWS_ERROR(status);
-
- brokerHost = host;
- // Note that the following logic does not cause a memory leak.
- // The allocated Socket is freed either by the AsynchConnector
- // upon connection failure or by the AsynchIO upon connection
- // shutdown. The allocated AsynchConnector frees itself when it
- // is no longer needed.
- qpid::sys::Socket* socket = new qpid::sys::Socket();
- connectFailedCallback = failed;
- AsynchConnector::create(*socket,
- host,
- port,
- boost::bind(&SslProtocolFactory::established,
- this, poller, _1, fact, true),
- boost::bind(&SslProtocolFactory::connectFailed,
- this, _1, _2, _3));
-}
-
-namespace
-{
-const std::string SSL = "ssl";
-}
-
-bool SslProtocolFactory::supports(const std::string& capability)
-{
- std::string s = capability;
- transform(s.begin(), s.end(), s.begin(), tolower);
- return s == SSL;
-}
-
-}}} // namespace qpid::sys::windows