diff options
author | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
---|---|---|
committer | Rajith Muditha Attapattu <rajith@apache.org> | 2011-05-27 15:44:23 +0000 |
commit | 66765100f4257159622cefe57bed50125a5ad017 (patch) | |
tree | a88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /qpid/cpp/include | |
parent | 1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff) | |
parent | 88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff) | |
download | qpid-python-rajith_jms_client.tar.gz |
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/include')
141 files changed, 13791 insertions, 0 deletions
diff --git a/qpid/cpp/include/qmf/Agent.h b/qpid/cpp/include/qmf/Agent.h new file mode 100644 index 0000000000..94083be4f3 --- /dev/null +++ b/qpid/cpp/include/qmf/Agent.h @@ -0,0 +1,133 @@ +#ifndef QMF_AGENT_H +#define QMF_AGENT_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +//#include "qmf/Subscription.h" +#include "qmf/exceptions.h" +#include "qpid/messaging/Duration.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class AgentImpl; + class ConsoleEvent; + class Query; + class DataAddr; + class SchemaId; + class Schema; + + class QMF_CLASS_EXTERN Agent : public qmf::Handle<AgentImpl> { + public: + QMF_EXTERN Agent(AgentImpl* impl = 0); + QMF_EXTERN Agent(const Agent&); + QMF_EXTERN Agent& operator=(const Agent&); + QMF_EXTERN ~Agent(); + + QMF_EXTERN std::string getName() const; + QMF_EXTERN uint32_t getEpoch() const; + QMF_EXTERN std::string getVendor() const; + QMF_EXTERN std::string getProduct() const; + QMF_EXTERN std::string getInstance() const; + QMF_EXTERN const qpid::types::Variant& getAttribute(const std::string&) const; + QMF_EXTERN const qpid::types::Variant::Map& getAttributes() const; + + QMF_EXTERN ConsoleEvent query(const Query&, qpid::messaging::Duration timeout=qpid::messaging::Duration::MINUTE); + QMF_EXTERN ConsoleEvent query(const std::string&, qpid::messaging::Duration timeout=qpid::messaging::Duration::MINUTE); + QMF_EXTERN uint32_t queryAsync(const Query&); + QMF_EXTERN uint32_t queryAsync(const std::string&); + + /** + * Create a subscription to this agent + */ + //QMF_EXTERN Subscription subscribe(const Query&, const std::string& options = ""); + //QMF_EXTERN Subscription subscribe(const std::string&, const std::string& options = ""); + + QMF_EXTERN ConsoleEvent callMethod(const std::string&, const qpid::types::Variant::Map&, const DataAddr&, + qpid::messaging::Duration timeout=qpid::messaging::Duration::MINUTE); + QMF_EXTERN uint32_t callMethodAsync(const std::string&, const qpid::types::Variant::Map&, const DataAddr&); + + /** + * Query the agent for a list of schema classes that it exposes. This operation comes in both + * synchronous (blocking) and asynchronous flavors. + * + * This method will typically be used after receiving an AGENT_SCHEMA_UPDATE event from the console session. + * It may also be used on a newly discovered agent to learn what schemata are exposed. + * + * querySchema returns a ConsoleEvent that contains a list of SchemaId objects exposed by the agent. + * This list is cached locally and can be locally queried using getPackage[Count] and getSchemaId[Count]. + */ + QMF_EXTERN ConsoleEvent querySchema(qpid::messaging::Duration timeout=qpid::messaging::Duration::MINUTE); + QMF_EXTERN uint32_t querySchemaAsync(); + + /** + * Get the list of schema packages exposed by the agent. + * + * getPackageCount returns the number of packages exposed. + * getPackage returns the name of the package by index (0..package-count) + * + * Note that both of these calls are synchronous and non-blocking. They only return locally cached data + * and will not send any messages to the remote agent. Use querySchema[Async] to get the latest schema + * information from the remote agent. + */ + QMF_EXTERN uint32_t getPackageCount() const; + QMF_EXTERN const std::string& getPackage(uint32_t) const; + + /** + * Get the list of schema identifiers for a particular package. + * + * getSchemaIdCount returns the number of IDs in the indicates package. + * getSchemaId returns the SchemaId by index (0..schema-id-count) + * + * Note that both of these calls are synchronous and non-blocking. They only return locally cached data + * and will not send any messages to the remote agent. Use querySchema[Async] to get the latest schema + * information from the remote agent. + */ + QMF_EXTERN uint32_t getSchemaIdCount(const std::string&) const; + QMF_EXTERN SchemaId getSchemaId(const std::string&, uint32_t) const; + + /** + * Get detailed schema information for a specified schema ID. + * + * This call will return cached information if it is available. If not, it will send a query message to the + * remote agent and block waiting for a response. The timeout argument specifies the maximum time to wait + * for a response from the agent. + */ + QMF_EXTERN Schema getSchema(const SchemaId&, qpid::messaging::Duration timeout=qpid::messaging::Duration::MINUTE); + + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<Agent>; + friend struct AgentImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/AgentEvent.h b/qpid/cpp/include/qmf/AgentEvent.h new file mode 100644 index 0000000000..0f93a9bb0a --- /dev/null +++ b/qpid/cpp/include/qmf/AgentEvent.h @@ -0,0 +1,74 @@ +#ifndef QMF_AGENT_EVENT_H +#define QMF_AGENT_EVENT_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/types/Variant.h" + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class AgentEventImpl; + class Query; + class DataAddr; + + enum AgentEventCode { + AGENT_AUTH_QUERY = 1, + AGENT_AUTH_SUBSCRIBE = 2, + AGENT_QUERY = 3, + AGENT_METHOD = 4, + AGENT_SUBSCRIBE_BEGIN = 5, + AGENT_SUBSCRIBE_TOUCH = 6, + AGENT_SUBSCRIBE_END = 7, + AGENT_THREAD_FAILED = 8 + }; + + class QMF_CLASS_EXTERN AgentEvent : public qmf::Handle<AgentEventImpl> { + public: + QMF_EXTERN AgentEvent(AgentEventImpl* impl = 0); + QMF_EXTERN AgentEvent(const AgentEvent&); + QMF_EXTERN AgentEvent& operator=(const AgentEvent&); + QMF_EXTERN ~AgentEvent(); + + QMF_EXTERN AgentEventCode getType() const; + QMF_EXTERN const std::string& getUserId() const; + QMF_EXTERN Query getQuery() const; + QMF_EXTERN bool hasDataAddr() const; + QMF_EXTERN DataAddr getDataAddr() const; + QMF_EXTERN const std::string& getMethodName() const; + QMF_EXTERN qpid::types::Variant::Map& getArguments(); + QMF_EXTERN qpid::types::Variant::Map& getArgumentSubtypes(); + QMF_EXTERN void addReturnArgument(const std::string&, const qpid::types::Variant&, const std::string& st=""); + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<AgentEvent>; + friend struct AgentEventImplAccess; +#endif + }; +} + +#endif diff --git a/qpid/cpp/include/qmf/AgentSession.h b/qpid/cpp/include/qmf/AgentSession.h new file mode 100644 index 0000000000..1eeb252143 --- /dev/null +++ b/qpid/cpp/include/qmf/AgentSession.h @@ -0,0 +1,191 @@ +#ifndef QMF_AGENT_SESSION_H +#define QMF_AGENT_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/messaging/Duration.h" +#include "qpid/messaging/Connection.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class AgentSessionImpl; + class AgentEvent; + class Schema; + class Data; + class DataAddr; + + class QMF_CLASS_EXTERN AgentSession : public qmf::Handle<AgentSessionImpl> { + public: + QMF_EXTERN AgentSession(AgentSessionImpl* impl = 0); + QMF_EXTERN AgentSession(const AgentSession&); + QMF_EXTERN AgentSession& operator=(const AgentSession&); + QMF_EXTERN ~AgentSession(); + + /** + * AgentSession + * A session that runs over an AMQP connection for QMF agent operation. + * + * @param connection - An opened qpid::messaging::Connection + * @param options - An optional string containing options + * + * The options string is of the form "{key:value,key:value}". The following keys are supported: + * + * interval:N - Heartbeat interval in seconds [default: 60] + * external:{True,False} - Use external data storage (queries and subscriptions are pass-through) [default: False] + * allow-queries:{True,False} - If True: automatically allow all queries [default] + * If False: generate an AUTH_QUERY event to allow per-query authorization + * allow-methods:{True,False} - If True: automatically allow all methods [default] + * If False: generate an AUTH_METHOD event to allow per-method authorization + * max-subscriptions:N - Maximum number of concurrent subscription queries permitted [default: 64] + * min-sub-interval:N - Minimum publish interval (in milliseconds) permitted for a subscription [default: 3000] + * sub-lifetime:N - Lifetime (in seconds with no keepalive) for a subscription [default: 300] + * public-events:{True,False} - If True: QMF events are sent to the topic exchange [default] + * If False: QMF events are only sent to authorized subscribers + * listen-on-direct:{True,False} - If True: Listen on legacy direct-exchange address for backward compatibility [default] + * If False: Listen only on the routable direct address + * strict-security:{True,False} - If True: Cooperate with the broker to enforce strict access control to the network + * - If False: Operate more flexibly with regard to use of messaging facilities [default] + */ + QMF_EXTERN AgentSession(qpid::messaging::Connection& conn, const std::string& options=""); + + /** + * setDomain - Change the QMF domain that this agent will operate in. If this is not called, + * the domain will be "default". Agents in a domain can be seen only by consoles in the same domain. + * This must be called prior to opening the agent session. + */ + QMF_EXTERN void setDomain(const std::string& domain); + + /** + * Set identifying attributes of this agent. + * setVendor - Set the vendor string + * setProduct - Set the product name string + * setInstance - Set the unique instance name (if not set, a UUID will be assigned) + * These must be called prior to opening the agent session. + */ + QMF_EXTERN void setVendor(const std::string& vendor); + QMF_EXTERN void setProduct(const std::string& product); + QMF_EXTERN void setInstance(const std::string& instance); + + /** + * setAttribute - Set an arbitrary attribute for this agent. The attributes are not used + * to uniquely identify the agent but can be used as a search criteria when looking for agents. + * This must be called prior to opening the agent session. + */ + QMF_EXTERN void setAttribute(const std::string& key, const qpid::types::Variant& value); + + /** + * Get the identifying name of the agent. + */ + QMF_EXTERN const std::string& getName() const; + + /** + * Open the agent session. After opening the session, the domain, identifying strings, and attributes cannot + * be changed. + */ + QMF_EXTERN void open(); + + /** + * Close the session. Once closed, the session no longer communicates on the messaging network. + */ + QMF_EXTERN void close(); + + /** + * Get the next event from the agent session. Events represent actions that must be acted upon by the + * agent application. This method blocks for up to the timeout if there are no events to be handled. + * This method will typically be the focus of the agent application's main execution loop. + * If the timeout is set to Duration::IMMEDIATE, the call will not block. + */ + QMF_EXTERN bool nextEvent(AgentEvent& outEvent, qpid::messaging::Duration timeout=qpid::messaging::Duration::FOREVER); + + /** + * Return the number of events pending for nextEvent. This method will never block. + */ + QMF_EXTERN int pendingEvents() const; + + /** + * Register a schema to be exposed by this agent. + */ + QMF_EXTERN void registerSchema(Schema& schema); + + /** + * Add data to be managed internally by the agent. If the option external:True is selected, this call + * should not be used. + * + * @param data - The data object being managed by the agent. + * @param name - A name unique to this object to be used to address the object. + * If left default, a unique name will be assigned by the agent. + * @param persistent - Set this to true if the data object is to be considered persistent + * across different sessions. If persistent, it is the agent application's + * responsibility to ensure the name is the same each time it is added. + */ + QMF_EXTERN DataAddr addData(Data& data, const std::string& name="", bool persistent=false); + + /** + * Delete data from internal agent management. + */ + QMF_EXTERN void delData(const DataAddr& dataAddr); + + /** + * The following methods are used to respond to events received in nextEvent. + * + * authAccept - Accept an authorization request. + * authReject - Reject/forbid an authorization request. + * raiseException - indicate failure of an operation (i.e. query or method call). + * response - Provide data in response to a query (only for option: external:True) + * complete - Indicate that the response to a query is complete (external:True only) + * methodSuccess - Indicate the successful completion of a method call. + */ + QMF_EXTERN void authAccept(AgentEvent& event); + QMF_EXTERN void authReject(AgentEvent& event, const std::string& diag=""); + QMF_EXTERN void raiseException(AgentEvent& event, const std::string& errorText); + QMF_EXTERN void raiseException(AgentEvent& event, const Data& errorData); + QMF_EXTERN void response(AgentEvent& event, const Data& responseData); + QMF_EXTERN void complete(AgentEvent& event); + QMF_EXTERN void methodSuccess(AgentEvent& event); + + /** + * Raise an event to be sent into the QMF network. + * + * @param data - A data object that contains the event contents. + * @param severity - Explicit severity (from qmf/SchemaTypes.h). If omitted, the severity is set to + * the default severity for the data's schema. If the data has no schema, the severity defaults + * to SEV_NOTICE. + */ + QMF_EXTERN void raiseEvent(const Data& data); + QMF_EXTERN void raiseEvent(const Data& data, int severity); + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<AgentSession>; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/ConsoleEvent.h b/qpid/cpp/include/qmf/ConsoleEvent.h new file mode 100644 index 0000000000..94600f9357 --- /dev/null +++ b/qpid/cpp/include/qmf/ConsoleEvent.h @@ -0,0 +1,89 @@ +#ifndef QMF_CONSOLE_EVENT_H +#define QMF_CONSOLE_EVENT_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qmf/Agent.h" +#include "qmf/Data.h" +#include "qmf/SchemaId.h" +#include "qpid/types/Variant.h" + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class ConsoleEventImpl; + + enum ConsoleEventCode { + CONSOLE_AGENT_ADD = 1, + CONSOLE_AGENT_DEL = 2, + CONSOLE_AGENT_RESTART = 3, + CONSOLE_AGENT_SCHEMA_UPDATE = 4, + CONSOLE_AGENT_SCHEMA_RESPONSE = 5, + CONSOLE_EVENT = 6, + CONSOLE_QUERY_RESPONSE = 7, + CONSOLE_METHOD_RESPONSE = 8, + CONSOLE_EXCEPTION = 9, + CONSOLE_SUBSCRIBE_ADD = 10, + CONSOLE_SUBSCRIBE_UPDATE = 11, + CONSOLE_SUBSCRIBE_DEL = 12, + CONSOLE_THREAD_FAILED = 13 + }; + + enum AgentDelReason { + AGENT_DEL_AGED = 1, + AGENT_DEL_FILTER = 2 + }; + + class QMF_CLASS_EXTERN ConsoleEvent : public qmf::Handle<ConsoleEventImpl> { + public: + QMF_EXTERN ConsoleEvent(ConsoleEventImpl* impl = 0); + QMF_EXTERN ConsoleEvent(const ConsoleEvent&); + QMF_EXTERN ConsoleEvent& operator=(const ConsoleEvent&); + QMF_EXTERN ~ConsoleEvent(); + + QMF_EXTERN ConsoleEventCode getType() const; + QMF_EXTERN uint32_t getCorrelator() const; + QMF_EXTERN Agent getAgent() const; + QMF_EXTERN AgentDelReason getAgentDelReason() const; + QMF_EXTERN uint32_t getSchemaIdCount() const; + QMF_EXTERN SchemaId getSchemaId(uint32_t) const; + QMF_EXTERN uint32_t getDataCount() const; + QMF_EXTERN Data getData(uint32_t) const; + QMF_EXTERN bool isFinal() const; + QMF_EXTERN const qpid::types::Variant::Map& getArguments() const; + QMF_EXTERN int getSeverity() const; + QMF_EXTERN uint64_t getTimestamp() const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<ConsoleEvent>; + friend struct ConsoleEventImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/ConsoleSession.h b/qpid/cpp/include/qmf/ConsoleSession.h new file mode 100644 index 0000000000..6008036eec --- /dev/null +++ b/qpid/cpp/include/qmf/ConsoleSession.h @@ -0,0 +1,127 @@ +#ifndef QMF_CONSOLE_SESSION_H +#define QMF_CONSOLE_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qmf/Agent.h" +#include "qmf/Subscription.h" +#include "qpid/messaging/Duration.h" +#include "qpid/messaging/Connection.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class ConsoleSessionImpl; + class ConsoleEvent; + + class QMF_CLASS_EXTERN ConsoleSession : public qmf::Handle<ConsoleSessionImpl> { + public: + QMF_EXTERN ConsoleSession(ConsoleSessionImpl* impl = 0); + QMF_EXTERN ConsoleSession(const ConsoleSession&); + QMF_EXTERN ConsoleSession& operator=(const ConsoleSession&); + QMF_EXTERN ~ConsoleSession(); + + /** + * ConsoleSession + * A session that runs over an AMQP connection for QMF console operation. + * + * @param connection - An opened qpid::messaging::Connection + * @param options - An optional string containing options + * + * The options string is of the form "{key:value,key:value}". The following keys are supported: + * + * domain:NAME - QMF Domain to join [default: "default"] + * max-agent-age:N - Maximum time, in minutes, that we will tolerate not hearing from + * an agent before deleting it [default: 5] + * listen-on-direct:{True,False} - If True: Listen on legacy direct-exchange address for backward compatibility [default] + * If False: Listen only on the routable direct address + * strict-security:{True,False} - If True: Cooperate with the broker to enforce strict access control to the network + * - If False: Operate more flexibly with regard to use of messaging facilities [default] + */ + QMF_EXTERN ConsoleSession(qpid::messaging::Connection& conn, const std::string& options=""); + + /** + * setDomain - Change the QMF domain that this console will operate in. If this is not called, + * the domain will be "default". Agents in a domain can be seen only by consoles in the same domain. + * This must be called prior to opening the console session. + */ + QMF_EXTERN void setDomain(const std::string& domain); + QMF_EXTERN void setAgentFilter(const std::string& filter); + + /** + * Open the console session. After opening the session, the domain cannot be changed. + */ + QMF_EXTERN void open(); + + /** + * Close the session. Once closed, the session no longer communicates on the messaging network. + */ + QMF_EXTERN void close(); + + /** + * Get the next event from the console session. Events represent actions that must be acted upon by the + * console application. This method blocks for up to the timeout if there are no events to be handled. + * This method will typically be the focus of the console application's main execution loop. + * If the timeout is set to Duration::IMMEDIATE, the call will not block. + */ + QMF_EXTERN bool nextEvent(ConsoleEvent& outEvent, qpid::messaging::Duration timeout=qpid::messaging::Duration::FOREVER); + + /** + * Return the number of events pending for nextEvent. This method will never block. + */ + QMF_EXTERN int pendingEvents() const; + + /** + * getAgentCount, getAgent - Retrieve the set of agents that match the console session's agent filter. + */ + QMF_EXTERN uint32_t getAgentCount() const; + QMF_EXTERN Agent getAgent(uint32_t agentIndex) const; + + /** + * Get the agent for the connected broker (i.e. the agent embedded in the broker to which we have a connection). + */ + QMF_EXTERN Agent getConnectedBrokerAgent() const; + + /** + * Create a subscription that involves a subset of the known agents. The set of known agents is defined by + * the session's agent-filter (see setAgentFilter). The agentFilter argument to the subscribe method is used + * to further refine the set of agents. If agentFilter is the empty string (i.e. match-all) the subscription + * will involve all known agents. If agentFilter is non-empty, it will be applied only to the set of known + * agents. A subscription cannot be created that involves an agent not known by the session. + */ + QMF_EXTERN Subscription subscribe(const Query& query, const std::string& agentFilter = "", const std::string& options = ""); + QMF_EXTERN Subscription subscribe(const std::string& query, const std::string& agentFilter = "", const std::string& options = ""); + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<ConsoleSession>; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/Data.h b/qpid/cpp/include/qmf/Data.h new file mode 100644 index 0000000000..487a02fe95 --- /dev/null +++ b/qpid/cpp/include/qmf/Data.h @@ -0,0 +1,71 @@ +#ifndef QMF_DATA_H +#define QMF_DATA_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qmf/exceptions.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class DataImpl; + class Schema; + class SchemaId; + class DataAddr; + class Agent; + + class QMF_CLASS_EXTERN Data : public qmf::Handle<DataImpl> { + public: + QMF_EXTERN Data(DataImpl* impl = 0); + QMF_EXTERN Data(const Data&); + QMF_EXTERN Data& operator=(const Data&); + QMF_EXTERN ~Data(); + + QMF_EXTERN Data(const Schema&); + QMF_EXTERN void setAddr(const DataAddr&); + QMF_EXTERN void setProperty(const std::string&, const qpid::types::Variant&); + QMF_EXTERN void overwriteProperties(const qpid::types::Variant::Map&); + QMF_EXTERN bool hasSchema() const; + QMF_EXTERN bool hasAddr() const; + QMF_EXTERN const SchemaId& getSchemaId() const; + QMF_EXTERN const DataAddr& getAddr() const; + QMF_EXTERN const qpid::types::Variant& getProperty(const std::string&) const; + QMF_EXTERN const qpid::types::Variant::Map& getProperties() const; + QMF_EXTERN bool hasAgent() const; + QMF_EXTERN const Agent& getAgent() const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<Data>; + friend struct DataImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/DataAddr.h b/qpid/cpp/include/qmf/DataAddr.h new file mode 100644 index 0000000000..63d309cc4b --- /dev/null +++ b/qpid/cpp/include/qmf/DataAddr.h @@ -0,0 +1,63 @@ +#ifndef QMF_DATA_ADDR_H +#define QMF_DATA_ADDR_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class DataAddrImpl; + + class QMF_CLASS_EXTERN DataAddr : public qmf::Handle<DataAddrImpl> { + public: + QMF_EXTERN DataAddr(DataAddrImpl* impl = 0); + QMF_EXTERN DataAddr(const DataAddr&); + QMF_EXTERN DataAddr& operator=(const DataAddr&); + QMF_EXTERN ~DataAddr(); + + QMF_EXTERN bool operator==(const DataAddr&); + QMF_EXTERN bool operator<(const DataAddr&); + + QMF_EXTERN DataAddr(const qpid::types::Variant::Map&); + QMF_EXTERN DataAddr(const std::string& name, const std::string& agentName, uint32_t agentEpoch=0); + QMF_EXTERN const std::string& getName() const; + QMF_EXTERN const std::string& getAgentName() const; + QMF_EXTERN uint32_t getAgentEpoch() const; + QMF_EXTERN qpid::types::Variant::Map asMap() const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<DataAddr>; + friend struct DataAddrImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/Handle.h b/qpid/cpp/include/qmf/Handle.h new file mode 100644 index 0000000000..50971ea626 --- /dev/null +++ b/qpid/cpp/include/qmf/Handle.h @@ -0,0 +1,70 @@ +#ifndef QMF_HANDLE_H +#define QMF_HANDLE_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 "qmf/ImportExport.h" + +namespace qmf { + +template <class> class PrivateImplRef; + +/** \ingroup qmf + * A handle is like a pointer: refers to an underlying implementation object. + * Copying the handle does not copy the object. + * + * Handles can be null, like a 0 pointer. Use isValid(), isNull() or the + * conversion to bool to test for a null handle. + */ +template <class T> class Handle { + public: + + /**@return true if handle is valid, i.e. not null. */ + QMF_INLINE_EXTERN bool isValid() const { return impl; } + + /**@return true if handle is null. It is an error to call any function on a null handle. */ + QMF_INLINE_EXTERN bool isNull() const { return !impl; } + + /** Conversion to bool supports idiom if (handle) { handle->... } */ + QMF_INLINE_EXTERN operator bool() const { return impl; } + + /** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */ + QMF_INLINE_EXTERN bool operator !() const { return !impl; } + + void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; } + + protected: + typedef T Impl; + QMF_INLINE_EXTERN Handle() :impl() {} + + // Not implemented,subclasses must implement. + QMF_EXTERN Handle(const Handle&); + QMF_EXTERN Handle& operator=(const Handle&); + + Impl* impl; + + friend class PrivateImplRef<T>; +}; + +} // namespace qmf + +#endif /*!QMF_HANDLE_H*/ diff --git a/qpid/cpp/include/qmf/ImportExport.h b/qpid/cpp/include/qmf/ImportExport.h new file mode 100644 index 0000000000..7405c15259 --- /dev/null +++ b/qpid/cpp/include/qmf/ImportExport.h @@ -0,0 +1,35 @@ +#ifndef QMF_IMPORT_EXPORT_H +#define QMF_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. + */ + +#include "qpid/ImportExport.h" + +#if defined(QMF_EXPORT) || defined (qmf2_EXPORTS) +# define QMF_EXTERN QPID_EXPORT +# define QMF_CLASS_EXTERN QPID_CLASS_EXPORT +# define QMF_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QMF_EXTERN QPID_IMPORT +# define QMF_CLASS_EXTERN QPID_CLASS_IMPORT +# define QMF_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif diff --git a/qpid/cpp/include/qmf/Query.h b/qpid/cpp/include/qmf/Query.h new file mode 100644 index 0000000000..c1264f8901 --- /dev/null +++ b/qpid/cpp/include/qmf/Query.h @@ -0,0 +1,74 @@ +#ifndef QMF_QUERY_H +#define QMF_QUERY_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class QueryImpl; + class SchemaId; + class DataAddr; + + enum QueryTarget { + QUERY_OBJECT = 1, + QUERY_OBJECT_ID = 2, + QUERY_SCHEMA = 3, + QUERY_SCHEMA_ID = 4 + }; + + class QMF_CLASS_EXTERN Query : public qmf::Handle<QueryImpl> { + public: + QMF_EXTERN Query(QueryImpl* impl = 0); + QMF_EXTERN Query(const Query&); + QMF_EXTERN Query& operator=(const Query&); + QMF_EXTERN ~Query(); + + QMF_EXTERN Query(QueryTarget, const std::string& predicate=""); + QMF_EXTERN Query(QueryTarget, const std::string& className, const std::string& package, const std::string& predicate=""); + QMF_EXTERN Query(QueryTarget, const SchemaId&, const std::string& predicate=""); + QMF_EXTERN Query(const DataAddr&); + + QMF_EXTERN QueryTarget getTarget() const; + QMF_EXTERN const DataAddr& getDataAddr() const; + QMF_EXTERN const SchemaId& getSchemaId() const; + QMF_EXTERN void setPredicate(const qpid::types::Variant::List&); + QMF_EXTERN const qpid::types::Variant::List& getPredicate() const; + QMF_EXTERN bool matchesPredicate(const qpid::types::Variant::Map& map) const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<Query>; + friend struct QueryImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/Schema.h b/qpid/cpp/include/qmf/Schema.h new file mode 100644 index 0000000000..6cfd2e2a56 --- /dev/null +++ b/qpid/cpp/include/qmf/Schema.h @@ -0,0 +1,76 @@ +#ifndef QMF_SCHEMA_H +#define QMF_SCHEMA_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 <qmf/ImportExport.h> +#include "qpid/sys/IntegerTypes.h" +#include "qmf/Handle.h" +#include "qmf/SchemaTypes.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class SchemaImpl; + class SchemaId; + class SchemaProperty; + class SchemaMethod; + + class QMF_CLASS_EXTERN Schema : public qmf::Handle<SchemaImpl> { + public: + QMF_EXTERN Schema(SchemaImpl* impl = 0); + QMF_EXTERN Schema(const Schema&); + QMF_EXTERN Schema& operator=(const Schema&); + QMF_EXTERN ~Schema(); + + QMF_EXTERN Schema(int, const std::string&, const std::string&); + QMF_EXTERN const SchemaId& getSchemaId() const; + + QMF_EXTERN void finalize(); + QMF_EXTERN bool isFinalized() const; + QMF_EXTERN void addProperty(const SchemaProperty&); + QMF_EXTERN void addMethod(const SchemaMethod&); + QMF_EXTERN void setDesc(const std::string&); + QMF_EXTERN const std::string& getDesc() const; + + QMF_EXTERN void setDefaultSeverity(int); + QMF_EXTERN int getDefaultSeverity() const; + + QMF_EXTERN uint32_t getPropertyCount() const; + QMF_EXTERN SchemaProperty getProperty(uint32_t) const; + + QMF_EXTERN uint32_t getMethodCount() const; + QMF_EXTERN SchemaMethod getMethod(uint32_t) const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<Schema>; + friend struct SchemaImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/SchemaId.h b/qpid/cpp/include/qmf/SchemaId.h new file mode 100644 index 0000000000..2dafc1c091 --- /dev/null +++ b/qpid/cpp/include/qmf/SchemaId.h @@ -0,0 +1,61 @@ +#ifndef QMF_SCHEMA_ID_H +#define QMF_SCHEMA_ID_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/types/Uuid.h" +#include "qmf/SchemaTypes.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class SchemaIdImpl; + + class QMF_CLASS_EXTERN SchemaId : public qmf::Handle<SchemaIdImpl> { + public: + QMF_EXTERN SchemaId(SchemaIdImpl* impl = 0); + QMF_EXTERN SchemaId(const SchemaId&); + QMF_EXTERN SchemaId& operator=(const SchemaId&); + QMF_EXTERN ~SchemaId(); + + QMF_EXTERN SchemaId(int, const std::string&, const std::string&); + QMF_EXTERN void setHash(const qpid::types::Uuid&); + QMF_EXTERN int getType() const; + QMF_EXTERN const std::string& getPackageName() const; + QMF_EXTERN const std::string& getName() const; + QMF_EXTERN const qpid::types::Uuid& getHash() const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<SchemaId>; + friend struct SchemaIdImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/SchemaMethod.h b/qpid/cpp/include/qmf/SchemaMethod.h new file mode 100644 index 0000000000..b5944dc29e --- /dev/null +++ b/qpid/cpp/include/qmf/SchemaMethod.h @@ -0,0 +1,65 @@ +#ifndef QMF_SCHEMA_METHOD_H +#define QMF_SCHEMA_METHOD_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 "qmf/ImportExport.h" +#include "qpid/sys/IntegerTypes.h" +#include "qmf/Handle.h" +#include "qmf/SchemaTypes.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class SchemaMethodImpl; + class SchemaProperty; + + class QMF_CLASS_EXTERN SchemaMethod : public qmf::Handle<SchemaMethodImpl> { + public: + QMF_EXTERN SchemaMethod(SchemaMethodImpl* impl = 0); + QMF_EXTERN SchemaMethod(const SchemaMethod&); + QMF_EXTERN SchemaMethod& operator=(const SchemaMethod&); + QMF_EXTERN ~SchemaMethod(); + + QMF_EXTERN SchemaMethod(const std::string&, const std::string& o=""); + + QMF_EXTERN void setDesc(const std::string&); + QMF_EXTERN void addArgument(const SchemaProperty&); + + QMF_EXTERN const std::string& getName() const; + QMF_EXTERN const std::string& getDesc() const; + QMF_EXTERN uint32_t getArgumentCount() const; + QMF_EXTERN SchemaProperty getArgument(uint32_t) const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<SchemaMethod>; + friend struct SchemaMethodImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/SchemaProperty.h b/qpid/cpp/include/qmf/SchemaProperty.h new file mode 100644 index 0000000000..bbb603fa50 --- /dev/null +++ b/qpid/cpp/include/qmf/SchemaProperty.h @@ -0,0 +1,75 @@ +#ifndef QMF_SCHEMA_PROPERTY_H +#define QMF_SCHEMA_PROPERTY_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/types/Uuid.h" +#include "qpid/types/Variant.h" +#include "qmf/SchemaTypes.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class SchemaPropertyImpl; + + class QMF_CLASS_EXTERN SchemaProperty : public Handle<SchemaPropertyImpl> { + public: + QMF_EXTERN SchemaProperty(SchemaPropertyImpl* impl = 0); + QMF_EXTERN SchemaProperty(const SchemaProperty&); + QMF_EXTERN SchemaProperty& operator=(const SchemaProperty&); + QMF_EXTERN ~SchemaProperty(); + + QMF_EXTERN SchemaProperty(const std::string&, int, const std::string& o=""); + + QMF_EXTERN void setAccess(int); + QMF_EXTERN void setIndex(bool); + QMF_EXTERN void setOptional(bool); + QMF_EXTERN void setUnit(const std::string&); + QMF_EXTERN void setDesc(const std::string&); + QMF_EXTERN void setSubtype(const std::string&); + QMF_EXTERN void setDirection(int); + + QMF_EXTERN const std::string& getName() const; + QMF_EXTERN int getType() const; + QMF_EXTERN int getAccess() const; + QMF_EXTERN bool isIndex() const; + QMF_EXTERN bool isOptional() const; + QMF_EXTERN const std::string& getUnit() const; + QMF_EXTERN const std::string& getDesc() const; + QMF_EXTERN const std::string& getSubtype() const; + QMF_EXTERN int getDirection() const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<SchemaProperty>; + friend struct SchemaPropertyImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/SchemaTypes.h b/qpid/cpp/include/qmf/SchemaTypes.h new file mode 100644 index 0000000000..af3da612e5 --- /dev/null +++ b/qpid/cpp/include/qmf/SchemaTypes.h @@ -0,0 +1,56 @@ +#ifndef QMF_SCHEMA_TYPES_H +#define QMF_SCHEMA_TYPES_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 qmf { + + const int SCHEMA_TYPE_DATA = 1; + const int SCHEMA_TYPE_EVENT = 2; + + const int SCHEMA_DATA_VOID = 1; + const int SCHEMA_DATA_BOOL = 2; + const int SCHEMA_DATA_INT = 3; + const int SCHEMA_DATA_FLOAT = 4; + const int SCHEMA_DATA_STRING = 5; + const int SCHEMA_DATA_MAP = 6; + const int SCHEMA_DATA_LIST = 7; + const int SCHEMA_DATA_UUID = 8; + + const int ACCESS_READ_CREATE = 1; + const int ACCESS_READ_WRITE = 2; + const int ACCESS_READ_ONLY = 3; + + const int DIR_IN = 1; + const int DIR_OUT = 2; + const int DIR_IN_OUT = 3; + + const int SEV_EMERG = 0; + const int SEV_ALERT = 1; + const int SEV_CRIT = 2; + const int SEV_ERROR = 3; + const int SEV_WARN = 4; + const int SEV_NOTICE = 5; + const int SEV_INFORM = 6; + const int SEV_DEBUG = 7; +} + +#endif diff --git a/qpid/cpp/include/qmf/Subscription.h b/qpid/cpp/include/qmf/Subscription.h new file mode 100644 index 0000000000..398a45b922 --- /dev/null +++ b/qpid/cpp/include/qmf/Subscription.h @@ -0,0 +1,82 @@ +#ifndef QMF_SUBSCRIPTION_H +#define QMF_SUBSCRIPTION_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 <qmf/ImportExport.h> +#include "qmf/Handle.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qmf { + +#ifndef SWIG + template <class> class PrivateImplRef; +#endif + + class SubscriptionImpl; + class Data; + + class QMF_CLASS_EXTERN Subscription : public qmf::Handle<SubscriptionImpl> { + public: + QMF_EXTERN Subscription(SubscriptionImpl* impl = 0); + QMF_EXTERN Subscription(const Subscription&); + QMF_EXTERN Subscription& operator=(const Subscription&); + QMF_EXTERN ~Subscription(); + + /** + * Construction: A subscription is created by calling ConsoleSession::subscribe. + */ + + /** + * Cancel subscriptions to all subscribed agents. After this is called, the subscription + * shall be inactive. + */ + QMF_EXTERN void cancel(); + + /** + * Check to see if this subscription is active. It is active if it has a live subscription + * on at least one agent. If it is not active, there is nothing that can be done to make it + * active, it can only be deleted. + */ + QMF_EXTERN bool isActive() const; + + /** + * lock and unlock should be used to bracket a traversal of the data set. After lock is called, + * the subscription will not change its set of available data objects. Between calls to getDataCount + * and getData, no data objects will be added or removed. After unlock is called, the set of data + * will catch up to any activity that occurred while the lock was in effect. + */ + QMF_EXTERN void lock(); + QMF_EXTERN void unlock(); + QMF_EXTERN uint32_t getDataCount() const; + QMF_EXTERN Data getData(uint32_t) const; + +#ifndef SWIG + private: + friend class qmf::PrivateImplRef<Subscription>; + friend struct SubscriptionImplAccess; +#endif + }; + +} + +#endif diff --git a/qpid/cpp/include/qmf/engine/Agent.h b/qpid/cpp/include/qmf/engine/Agent.h new file mode 100644 index 0000000000..71abf82254 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Agent.h @@ -0,0 +1,209 @@ +#ifndef _QmfEngineAgent_ +#define _QmfEngineAgent_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/Schema.h> +#include <qmf/engine/ObjectId.h> +#include <qmf/engine/Object.h> +#include <qmf/engine/Event.h> +#include <qmf/engine/Query.h> +#include <qmf/engine/Value.h> +#include <qmf/engine/Message.h> + +namespace qmf { +namespace engine { + + /** + * AgentEvent + * + * This structure represents a QMF event coming from the agent to + * the application. + */ + struct AgentEvent { + enum EventKind { + GET_QUERY = 1, + START_SYNC = 2, + END_SYNC = 3, + METHOD_CALL = 4, + DECLARE_QUEUE = 5, + DELETE_QUEUE = 6, + BIND = 7, + UNBIND = 8, + SETUP_COMPLETE = 9 + }; + + EventKind kind; + uint32_t sequence; // Protocol sequence (for all kinds) + char* authUserId; // Authenticated user ID (for all kinds) + char* authToken; // Authentication token if issued (for all kinds) + char* name; // Name of the method/sync query + // (METHOD_CALL, START_SYNC, END_SYNC, DECLARE_QUEUE, BIND, UNBIND) + Object* object; // Object involved in method call (METHOD_CALL) + ObjectId* objectId; // ObjectId for method call (METHOD_CALL) + Query* query; // Query parameters (GET_QUERY, START_SYNC) + Value* arguments; // Method parameters (METHOD_CALL) + char* exchange; // Exchange for bind (BIND, UNBIND) + char* bindingKey; // Key for bind (BIND, UNBIND) + const SchemaObjectClass* objectClass; // (METHOD_CALL) + }; + + class AgentImpl; + + /** + * Agent - Protocol engine for the QMF agent + */ + class Agent { + public: + Agent(char* label, bool internalStore=true); + ~Agent(); + + /** + * Configure the directory path for storing persistent data. + *@param path Null-terminated string containing a directory path where files can be + * created, written, and read. If NULL, no persistent storage will be + * attempted. + */ + void setStoreDir(const char* path); + + /** + * Configure the directory path for files transferred over QMF. + *@param path Null-terminated string containing a directory path where files can be + * created, deleted, written, and read. If NULL, file transfers shall not + * be permitted. + */ + void setTransferDir(const char* path); + + /** + * Pass messages received from the AMQP session to the Agent engine. + *@param message AMQP messages received on the agent session. + */ + void handleRcvMessage(Message& message); + + /** + * Get the next message to be sent to the AMQP network. + *@param item The Message structure describing the message to be produced. + *@return true if the Message is valid, false if there are no messages to send. + */ + bool getXmtMessage(Message& item) const; + + /** + * Remove and discard one message from the head of the transmit queue. + */ + void popXmt(); + + /** + * Get the next application event from the agent engine. + *@param event The event iff the return value is true + *@return true if event is valid, false if there are no events to process + */ + bool getEvent(AgentEvent& event) const; + + /** + * Remove and discard one event from the head of the event queue. + */ + void popEvent(); + + /** + * A new AMQP session has been established for Agent communication. + */ + void newSession(); + + /** + * Start the QMF Agent protocol. This should be invoked after a SETUP_COMPLETE event + * is received from the Agent engine. + */ + void startProtocol(); + + /** + * This method is called periodically so the agent can supply a heartbeat. + */ + void heartbeat(); + + /** + * Respond to a method request. + *@param sequence The sequence number from the method request event. + *@param status The method's completion status. + *@param text Status text ("OK" or an error message) + *@param arguments The list of output arguments from the method call. + */ + void methodResponse(uint32_t sequence, uint32_t status, char* text, const Value& arguments); + + /** + * Send a content indication to the QMF bus. This is only needed for objects that are + * managed by the application. This is *NOT* needed for objects managed by the Agent + * (inserted using addObject). + *@param sequence The sequence number of the GET request or the SYNC_START request. + *@param object The object (annotated with "changed" flags) for publication. + *@param prop If true, changed object properties are transmitted. + *@param stat If true, changed object statistics are transmitted. + */ + void queryResponse(uint32_t sequence, Object& object, bool prop = true, bool stat = true); + + /** + * Indicate the completion of a query. This is not used for SYNC_START requests. + *@param sequence The sequence number of the GET request. + */ + void queryComplete(uint32_t sequence); + + /** + * Register a schema class with the Agent. + *@param cls A SchemaObejctClass object that defines data managed by the agent. + */ + void registerClass(SchemaObjectClass* cls); + + /** + * Register a schema class with the Agent. + *@param cls A SchemaEventClass object that defines events sent by the agent. + */ + void registerClass(SchemaEventClass* cls); + + /** + * Give an object to the Agent for storage and management. Once added, the agent takes + * responsibility for the life cycle of the object. + *@param obj The object to be managed by the Agent. + *@param persistId A unique non-zero value if the object-id is to be persistent. + *@return The objectId of the managed object. + */ + const ObjectId* addObject(Object& obj, uint64_t persistId); + // const ObjectId* addObject(Object& obj, uint32_t persistIdLo, uint32_t persistIdHi); + + /** + * Allocate an object-id for an object that will be managed by the application. + *@param persistId A unique non-zero value if the object-id is to be persistent. + *@return The objectId structure for the allocated ID. + */ + const ObjectId* allocObjectId(uint64_t persistId); + const ObjectId* allocObjectId(uint32_t persistIdLo, uint32_t persistIdHi); + + /** + * Raise an event into the QMF network.. + *@param event The event object for the event to be raised. + */ + void raiseEvent(Event& event); + + private: + AgentImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/ConnectionSettings.h b/qpid/cpp/include/qmf/engine/ConnectionSettings.h new file mode 100644 index 0000000000..36312400b1 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/ConnectionSettings.h @@ -0,0 +1,150 @@ +#ifndef _QmfEngineConnectionSettings_ +#define _QmfEngineConnectionSettings_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 "qmf/engine/QmfEngineImportExport.h" +#include "qpid/sys/IntegerTypes.h" + +namespace qmf { +namespace engine { + + class ConnectionSettingsImpl; + class Value; + + /** + * Settings for AMQP connections to the broker. + * + * \ingroup qmfapi + */ + class ConnectionSettings { + public: + + /** + * Create a set of default connection settings. + * + * If no further attributes are set, the settings will cause a connection to be made to + * the default broker (on localhost or at a host/port supplied by service discovery) and + * authentication will be the best-available (GSSAPI/Kerberos, Anonymous, Plain with prompts + * for username and password). + */ + QMFE_EXTERN ConnectionSettings(); + + /** + * Create a set of connection settings by URL. + * + * @param url Universal resource locator describing the broker address and additional attributes. + * + * The URL is of the form: + * amqp[s]://host[:port][?key=value[&key=value]*] + * + * For example: + * amqp://localhost + * amqp://broker?transport=rdma&authmech=GSSAPI&authservice=qpidd + * amqps://broker?authmech=PLAIN&authuser=guest&authpass=guest + */ + QMFE_EXTERN ConnectionSettings(const char* url); + + /** + * Copy Constructor. + */ + ConnectionSettings(const ConnectionSettings& from); + + /** + * Destroy the connection settings object. + */ + QMFE_EXTERN ~ConnectionSettings(); + + /** + * Set an attribute to control connection setup. + * + * @param key A null-terminated string that is an attribute name. + * + * @param value Reference to a value to be stored as the attribute. The type of the value + * is specific to the key. + * + * @return True if success, False if invalid attribute + */ + QMFE_EXTERN bool setAttr(const char* key, const Value& value); + + /** + * Get the value of an attribute. + * + * @param key A null-terminated attribute name. + * + * @return The value associated with the attribute name. + */ + QMFE_EXTERN Value getAttr(const char* key) const; + + /** + * Get the attribute string (the portion of the URL following the '?') for the settings. + * + * @return A pointer to the attribute string. If the content of this string needs to be + * available beyond the scope of the calling function, it should be copied. The + * returned pointer may become invalid if the set of attributes is changed. + */ + QMFE_EXTERN const char* getAttrString() const; + + /** + * Shortcuts for setting the transport for the connection. + * + * @param port The port value for the connection address. + */ + QMFE_EXTERN void transportTcp(uint16_t port = 5672); + QMFE_EXTERN void transportSsl(uint16_t port = 5671); + QMFE_EXTERN void transportRdma(uint16_t port = 5672); + + /** + * Shortcuts for setting authentication mechanisms. + * + * @param username Null-terminated authentication user name. + * + * @param password Null-terminated authentication password. + * + * @param serviceName Null-terminated GSSAPI service name (Kerberos service principal) + * + * @param minSsf Minimum security factor for connections. 0 = encryption not required. + * + * @param maxSsf Maximum security factor for connections. 0 = encryption not permitted. + */ + QMFE_EXTERN void authAnonymous(const char* username = 0); + QMFE_EXTERN void authPlain(const char* username = 0, const char* password = 0); + QMFE_EXTERN void authGssapi(const char* serviceName, uint32_t minSsf = 0, uint32_t maxSsf = 256); + + /** + * Shortcut for setting connection retry attributes. + * + * @param delayMin Minimum delay (in seconds) between connection attempts. + * + * @param delaxMax Maximum delay (in seconds) between connection attempts. + * + * @param delayFactor Factor to multiply the delay by between failed connection attempts. + */ + QMFE_EXTERN void setRetry(int delayMin = 1, int delayMax = 128, int delayFactor = 2); + + private: + friend class ResilientConnectionImpl; + ConnectionSettingsImpl* impl; + }; + +} +} + +#endif diff --git a/qpid/cpp/include/qmf/engine/Console.h b/qpid/cpp/include/qmf/engine/Console.h new file mode 100644 index 0000000000..bd40c63c6c --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Console.h @@ -0,0 +1,239 @@ +#ifndef _QmfEngineConsole_ +#define _QmfEngineConsole_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/ResilientConnection.h> +#include <qmf/engine/Schema.h> +#include <qmf/engine/ObjectId.h> +#include <qmf/engine/Object.h> +#include <qmf/engine/Event.h> +#include <qmf/engine/Query.h> +#include <qmf/engine/Value.h> +#include <qmf/engine/Message.h> + +namespace qmf { +namespace engine { + + class Console; + class ConsoleImpl; + class BrokerProxyImpl; + class AgentProxy; + struct AgentProxyImpl; + struct MethodResponseImpl; + struct QueryResponseImpl; + struct QueryContext; + + /** + * + */ + class MethodResponse { + public: + MethodResponse(const MethodResponse& from); + ~MethodResponse(); + uint32_t getStatus() const; + const Value* getException() const; + const Value* getArgs() const; + + private: + friend struct MethodResponseImpl; + friend class ConsoleImpl; + MethodResponse(MethodResponseImpl* impl); + MethodResponseImpl* impl; + }; + + /** + * + */ + class QueryResponse { + public: + ~QueryResponse(); + uint32_t getStatus() const; + const Value* getException() const; + uint32_t getObjectCount() const; + const Object* getObject(uint32_t idx) const; + + private: + friend struct QueryResponseImpl; + friend struct QueryContext; + QueryResponse(QueryResponseImpl* impl); + QueryResponseImpl *impl; + }; + + /** + * + */ + struct ConsoleEvent { + enum EventKind { + AGENT_ADDED = 1, + AGENT_DELETED = 2, + NEW_PACKAGE = 3, + NEW_CLASS = 4, + OBJECT_UPDATE = 5, + EVENT_RECEIVED = 7, + AGENT_HEARTBEAT = 8 + }; + + EventKind kind; + AgentProxy* agent; // (AGENT_[ADDED|DELETED|HEARTBEAT]) + char* name; // (NEW_PACKAGE) + const SchemaClassKey* classKey; // (NEW_CLASS) + Object* object; // (OBJECT_UPDATE) + void* context; // (OBJECT_UPDATE) + Event* event; // (EVENT_RECEIVED) + uint64_t timestamp; // (AGENT_HEARTBEAT) + QueryResponse* queryResponse; // (QUERY_COMPLETE) + bool hasProps; + bool hasStats; + }; + + /** + * + */ + struct BrokerEvent { + enum EventKind { + BROKER_INFO = 10, + DECLARE_QUEUE = 11, + DELETE_QUEUE = 12, + BIND = 13, + UNBIND = 14, + SETUP_COMPLETE = 15, + STABLE = 16, + QUERY_COMPLETE = 17, + METHOD_RESPONSE = 18 + }; + + EventKind kind; + char* name; // ([DECLARE|DELETE]_QUEUE, [UN]BIND) + char* exchange; // ([UN]BIND) + char* bindingKey; // ([UN]BIND) + void* context; // (QUERY_COMPLETE, METHOD_RESPONSE) + QueryResponse* queryResponse; // (QUERY_COMPLETE) + MethodResponse* methodResponse; // (METHOD_RESPONSE) + }; + + /** + * + */ + class AgentProxy { + public: + AgentProxy(const AgentProxy& from); + ~AgentProxy(); + const char* getLabel() const; + uint32_t getBrokerBank() const; + uint32_t getAgentBank() const; + + private: + friend struct StaticContext; + friend struct QueryContext; + friend struct AgentProxyImpl; + friend class BrokerProxyImpl; + AgentProxy(AgentProxyImpl* impl); + AgentProxyImpl* impl; + }; + + /** + * + */ + class BrokerProxy { + public: + BrokerProxy(Console& console); + ~BrokerProxy(); + + void sessionOpened(SessionHandle& sh); + void sessionClosed(); + void startProtocol(); + + void handleRcvMessage(Message& message); + bool getXmtMessage(Message& item) const; + void popXmt(); + + bool getEvent(BrokerEvent& event) const; + void popEvent(); + + uint32_t agentCount() const; + const AgentProxy* getAgent(uint32_t idx) const; + void sendQuery(const Query& query, void* context, const AgentProxy* agent = 0); + + private: + friend class ConsoleImpl; + friend struct StaticContext; + BrokerProxyImpl* impl; + }; + + // TODO - move this to a public header + struct ConsoleSettings { + bool rcvObjects; + bool rcvEvents; + bool rcvHeartbeats; + bool userBindings; + + ConsoleSettings() : + rcvObjects(true), + rcvEvents(true), + rcvHeartbeats(true), + userBindings(false) {} + }; + + class Console { + public: + Console(const ConsoleSettings& settings = ConsoleSettings()); + ~Console(); + + bool getEvent(ConsoleEvent& event) const; + void popEvent(); + + void addConnection(BrokerProxy& broker, void* context); + void delConnection(BrokerProxy& broker); + + uint32_t packageCount() const; + const char* getPackageName(uint32_t idx) const; + + uint32_t classCount(const char* packageName) const; + const SchemaClassKey* getClass(const char* packageName, uint32_t idx) const; + + ClassKind getClassKind(const SchemaClassKey* key) const; + const SchemaObjectClass* getObjectClass(const SchemaClassKey* key) const; + const SchemaEventClass* getEventClass(const SchemaClassKey* key) const; + + void bindPackage(const char* packageName); + void bindClass(const SchemaClassKey* key); + void bindClass(const char* packageName, const char* className); + + void bindEvent(const SchemaClassKey *key); + void bindEvent(const char* packageName, const char* eventName); + + /* + void startSync(const Query& query, void* context, SyncQuery& sync); + void touchSync(SyncQuery& sync); + void endSync(SyncQuery& sync); + */ + + private: + friend class BrokerProxyImpl; + friend struct AgentProxyImpl; + friend struct StaticContext; + ConsoleImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/Event.h b/qpid/cpp/include/qmf/engine/Event.h new file mode 100644 index 0000000000..647b88dbf8 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Event.h @@ -0,0 +1,49 @@ +#ifndef _QmfEngineEvent_ +#define _QmfEngineEvent_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 qmf { +namespace engine { + + class SchemaEventClass; + class Value; + struct EventImpl; + + class Event { + public: + Event(const SchemaEventClass* type); + Event(const Event& from); + ~Event(); + + const SchemaEventClass* getClass() const; + Value* getValue(const char* key) const; + + private: + friend struct EventImpl; + friend class AgentImpl; + Event(EventImpl* impl); + EventImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/Message.h b/qpid/cpp/include/qmf/engine/Message.h new file mode 100644 index 0000000000..1e95cc6afe --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Message.h @@ -0,0 +1,41 @@ +#ifndef _QmfEngineMessage_ +#define _QmfEngineMessage_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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" + +namespace qmf { +namespace engine { + + struct Message { + char* body; + uint32_t length; + char* destination; + char* routingKey; + char* replyExchange; + char* replyKey; + char* userId; + }; + +} +} + +#endif diff --git a/qpid/cpp/include/qmf/engine/Object.h b/qpid/cpp/include/qmf/engine/Object.h new file mode 100644 index 0000000000..ad67cfdb95 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Object.h @@ -0,0 +1,56 @@ +#ifndef _QmfEngineObject_ +#define _QmfEngineObject_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/Schema.h> +#include <qmf/engine/ObjectId.h> +#include <qmf/engine/Value.h> + +namespace qmf { +namespace engine { + + struct ObjectImpl; + class Object { + public: + Object(const SchemaObjectClass* type); + Object(const Object& from); + virtual ~Object(); + + void destroy(); + const ObjectId* getObjectId() const; + void setObjectId(ObjectId* oid); + const SchemaObjectClass* getClass() const; + Value* getValue(const char* key) const; + void invokeMethod(const char* methodName, const Value* inArgs, void* context) const; + bool isDeleted() const; + void merge(const Object& from); + + private: + friend struct ObjectImpl; + friend class AgentImpl; + Object(ObjectImpl* impl); + ObjectImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/ObjectId.h b/qpid/cpp/include/qmf/engine/ObjectId.h new file mode 100644 index 0000000000..51eb2bc9e7 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/ObjectId.h @@ -0,0 +1,68 @@ +#ifndef _QmfEngineObjectId_ +#define _QmfEngineObjectId_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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> + +namespace qmf { +namespace engine { + + // TODO: Add to/from string and << operator + + struct ObjectIdImpl; + class ObjectId { + public: + ObjectId(); + ObjectId(const ObjectId& from); + ~ObjectId(); + + uint64_t getObjectNum() const; + uint32_t getObjectNumHi() const; + uint32_t getObjectNumLo() const; + bool isDurable() const; + const char* str() const; + uint8_t getFlags() const; + uint16_t getSequence() const; + uint32_t getBrokerBank() const; + uint32_t getAgentBank() const; + + bool operator==(const ObjectId& other) const; + bool operator<(const ObjectId& other) const; + bool operator>(const ObjectId& other) const; + bool operator<=(const ObjectId& other) const; + bool operator>=(const ObjectId& other) const; + ObjectId& operator=(const ObjectId &other); + + private: + friend struct ObjectIdImpl; + friend struct ObjectImpl; + friend class BrokerProxyImpl; + friend struct QueryImpl; + friend struct ValueImpl; + friend class AgentImpl; + ObjectId(ObjectIdImpl* impl); + ObjectIdImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h b/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h new file mode 100644 index 0000000000..cf8fffdb17 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h @@ -0,0 +1,42 @@ +#ifndef QMF_ENGINE_IMPORT_EXPORT_H +#define QMF_ENGINE_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(QMF_EXPORT) || defined (qmfengine_EXPORTS) +# define QMFE_EXTERN __declspec(dllexport) +# else +# define QMFE_EXTERN __declspec(dllimport) +# endif +# ifdef _MSC_VER +# define QMFE_CLASS_EXTERN +# define QMFE_INLINE_EXTERN QMFE_EXTERN +# else +# define QMFE_CLASS_EXTERN QMFE_EXTERN +# define QMFE_INLINE_EXTERN +# endif +#else +# define QMFE_EXTERN +# define QMFE_CLASS_EXTERN +# define QMFE_INLINE_EXTERN +#endif + +#endif diff --git a/qpid/cpp/include/qmf/engine/Query.h b/qpid/cpp/include/qmf/engine/Query.h new file mode 100644 index 0000000000..3ed08c5d8e --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Query.h @@ -0,0 +1,112 @@ +#ifndef _QmfEngineQuery_ +#define _QmfEngineQuery_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/ObjectId.h> +#include <qmf/engine/Value.h> + +namespace qmf { +namespace engine { + + class Object; + struct QueryElementImpl; + struct QueryImpl; + struct QueryExpressionImpl; + class SchemaClassKey; + + enum ValueOper { + O_EQ = 1, + O_NE = 2, + O_LT = 3, + O_LE = 4, + O_GT = 5, + O_GE = 6, + O_RE_MATCH = 7, + O_RE_NOMATCH = 8, + O_PRESENT = 9, + O_NOT_PRESENT = 10 + }; + + struct QueryOperand { + virtual ~QueryOperand() {} + virtual bool evaluate(const Object* object) const = 0; + }; + + struct QueryElement : public QueryOperand { + QueryElement(const char* attrName, const Value* value, ValueOper oper); + QueryElement(QueryElementImpl* impl); + virtual ~QueryElement(); + bool evaluate(const Object* object) const; + + QueryElementImpl* impl; + }; + + enum ExprOper { + E_NOT = 1, + E_AND = 2, + E_OR = 3, + E_XOR = 4 + }; + + struct QueryExpression : public QueryOperand { + QueryExpression(ExprOper oper, const QueryOperand* operand1, const QueryOperand* operand2); + QueryExpression(QueryExpressionImpl* impl); + virtual ~QueryExpression(); + bool evaluate(const Object* object) const; + + QueryExpressionImpl* impl; + }; + + class Query { + public: + Query(const char* className, const char* packageName); + Query(const SchemaClassKey* key); + Query(const ObjectId* oid); + Query(const Query& from); + ~Query(); + + void setSelect(const QueryOperand* criterion); + void setLimit(uint32_t maxResults); + void setOrderBy(const char* attrName, bool decreasing); + + const char* getPackage() const; + const char* getClass() const; + const ObjectId* getObjectId() const; + + bool haveSelect() const; + bool haveLimit() const; + bool haveOrderBy() const; + const QueryOperand* getSelect() const; + uint32_t getLimit() const; + const char* getOrderBy() const; + bool getDecreasing() const; + + private: + friend struct QueryImpl; + friend class BrokerProxyImpl; + Query(QueryImpl* impl); + QueryImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/ResilientConnection.h b/qpid/cpp/include/qmf/engine/ResilientConnection.h new file mode 100644 index 0000000000..c03d08cb96 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/ResilientConnection.h @@ -0,0 +1,173 @@ +#ifndef _QmfEngineResilientConnection_ +#define _QmfEngineResilientConnection_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/Message.h> +#include <qmf/engine/ConnectionSettings.h> +#include <string> + +namespace qmf { +namespace engine { + + class ResilientConnectionImpl; + + /** + * Represents events that occur, unsolicited, from ResilientConnection. + */ + struct ResilientConnectionEvent { + enum EventKind { + CONNECTED = 1, + DISCONNECTED = 2, + SESSION_CLOSED = 3, + RECV = 4 + }; + + EventKind kind; + void* sessionContext; // SESSION_CLOSED, RECV + char* errorText; // DISCONNECTED, SESSION_CLOSED + Message message; // RECV + }; + + class SessionHandle { + friend class ResilientConnectionImpl; + void* impl; + }; + + /** + * ResilientConnection represents a Qpid connection that is resilient. + * + * Upon creation, ResilientConnection attempts to establish a connection to the + * messaging broker. If it fails, it will continue to retry at an interval that + * increases over time (to a maximum interval). If an extablished connection is + * dropped, a reconnect will be attempted. + */ + class ResilientConnection { + public: + + /** + * Create a new resilient connection. + *@param settings Settings that define how the connection is to be made. + *@param delayMin Minimum delay (in seconds) between retries. + *@param delayMax Maximum delay (in seconds) between retries. + *@param delayFactor Factor to multiply retry delay by after each failure. + */ + ResilientConnection(const ConnectionSettings& settings); + ~ResilientConnection(); + + /** + * Get the connected status of the resilient connection. + *@return true iff the connection is established. + */ + bool isConnected() const; + + /** + * Get the next event (if present) from the connection. + *@param event Returned event if one is available. + *@return true if event is valid, false if there are no more events to handle. + */ + bool getEvent(ResilientConnectionEvent& event); + + /** + * Discard the event on the front of the queue. This should be invoked after processing + * the event from getEvent. + */ + void popEvent(); + + /** + * Create a new AMQP session. + *@param name Unique name for the session. + *@param sessionContext Optional user-context value that will be provided in events + * pertaining to this session. + *@param handle Output handle to be stored and used in subsequent calls pertaining to + * this session. + *@return true iff the session was successfully created. + */ + bool createSession(const char* name, void* sessionContext, SessionHandle& handle); + + /** + * Destroy a created session. + *@param handle SessionHandle returned by createSession. + */ + void destroySession(SessionHandle handle); + + /** + * Send a message into the AMQP broker via a session. + *@param handle The session handle of the session to transmit through. + *@param message The QMF message to transmit. + */ + void sendMessage(SessionHandle handle, Message& message); + + /** + * Declare an exclusive, auto-delete queue for a session. + *@param handle The session handle for the owner of the queue. + *@param queue The name of the queue. + */ + void declareQueue(SessionHandle handle, char* queue); + + /** + * Delete a queue. + *@param handle The session handle for the owner of the queue. + *@param queue The name of the queue. + */ + void deleteQueue(SessionHandle handle, char* queue); + + /** + * Bind a queue to an exchange. + *@param handle The session handle of the session to use for binding. + *@param exchange The name of the exchange for binding. + *@param queue The name of the queue for binding. + *@param key The binding key. + */ + void bind(SessionHandle handle, char* exchange, char* queue, char* key); + + /** + * Remove a binding. + *@param handle The session handle of the session to use for un-binding. + *@param exchange The name of the exchange. + *@param queue The name of the queue. + *@param key The binding key. + */ + void unbind(SessionHandle handle, char* exchange, char* queue, char* key); + + /** + * Establish a file descriptor for event notification. + *@param fd A file descriptor into which the connection shall write a character each + * time an event is enqueued. This fd may be in a pair, the other fd of which + * is used in a select loop to control execution. + */ + void setNotifyFd(int fd); + + /** + * Send a byte into the notify file descriptor. + * + * This can be used to wake up the event processing portion of the engine from either the + * wrapped implementation or the engine itself. + */ + void notify(); + + private: + ResilientConnectionImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/Schema.h b/qpid/cpp/include/qmf/engine/Schema.h new file mode 100644 index 0000000000..f53e84324a --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Schema.h @@ -0,0 +1,212 @@ +#ifndef _QmfEngineSchema_ +#define _QmfEngineSchema_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/Typecode.h> +#include <qpid/sys/IntegerTypes.h> + +namespace qmf { +namespace engine { + + enum Access { ACCESS_READ_CREATE = 1, ACCESS_READ_WRITE = 2, ACCESS_READ_ONLY = 3 }; + enum Direction { DIR_IN = 1, DIR_OUT = 2, DIR_IN_OUT = 3 }; + enum ClassKind { CLASS_OBJECT = 1, CLASS_EVENT = 2 }; + enum Severity { SEV_EMERG = 0, SEV_ALERT = 1, SEV_CRIT = 2, SEV_ERROR = 3, SEV_WARN = 4, SEV_NOTICE = 5, SEV_INFORM = 6, SEV_DEBUG = 7 }; + + struct SchemaArgumentImpl; + struct SchemaMethodImpl; + struct SchemaPropertyImpl; + struct SchemaStatisticImpl; + struct SchemaObjectClassImpl; + struct SchemaEventClassImpl; + struct SchemaClassKeyImpl; + + /** + */ + class SchemaArgument { + public: + SchemaArgument(const char* name, Typecode typecode); + SchemaArgument(const SchemaArgument& from); + ~SchemaArgument(); + void setDirection(Direction dir); + void setUnit(const char* val); + void setDesc(const char* desc); + const char* getName() const; + Typecode getType() const; + Direction getDirection() const; + const char* getUnit() const; + const char* getDesc() const; + + private: + friend struct SchemaArgumentImpl; + friend struct SchemaMethodImpl; + friend struct SchemaEventClassImpl; + SchemaArgument(SchemaArgumentImpl* impl); + SchemaArgumentImpl* impl; + }; + + /** + */ + class SchemaMethod { + public: + SchemaMethod(const char* name); + SchemaMethod(const SchemaMethod& from); + ~SchemaMethod(); + void addArgument(const SchemaArgument* argument); + void setDesc(const char* desc); + const char* getName() const; + const char* getDesc() const; + int getArgumentCount() const; + const SchemaArgument* getArgument(int idx) const; + + private: + friend struct SchemaMethodImpl; + friend struct SchemaObjectClassImpl; + friend class AgentImpl; + SchemaMethod(SchemaMethodImpl* impl); + SchemaMethodImpl* impl; + }; + + /** + */ + class SchemaProperty { + public: + SchemaProperty(const char* name, Typecode typecode); + SchemaProperty(const SchemaProperty& from); + ~SchemaProperty(); + void setAccess(Access access); + void setIndex(bool val); + void setOptional(bool val); + void setUnit(const char* val); + void setDesc(const char* desc); + const char* getName() const; + Typecode getType() const; + Access getAccess() const; + bool isIndex() const; + bool isOptional() const; + const char* getUnit() const; + const char* getDesc() const; + + private: + friend struct SchemaPropertyImpl; + friend struct SchemaObjectClassImpl; + SchemaProperty(SchemaPropertyImpl* impl); + SchemaPropertyImpl* impl; + }; + + /** + */ + class SchemaStatistic { + public: + SchemaStatistic(const char* name, Typecode typecode); + SchemaStatistic(const SchemaStatistic& from); + ~SchemaStatistic(); + void setUnit(const char* val); + void setDesc(const char* desc); + const char* getName() const; + Typecode getType() const; + const char* getUnit() const; + const char* getDesc() const; + + private: + friend struct SchemaStatisticImpl; + friend struct SchemaObjectClassImpl; + SchemaStatistic(SchemaStatisticImpl* impl); + SchemaStatisticImpl* impl; + }; + + /** + */ + class SchemaClassKey { + public: + SchemaClassKey(const SchemaClassKey& from); + ~SchemaClassKey(); + + const char* getPackageName() const; + const char* getClassName() const; + const uint8_t* getHash() const; + const char* asString() const; + + bool operator==(const SchemaClassKey& other) const; + bool operator<(const SchemaClassKey& other) const; + + private: + friend struct SchemaClassKeyImpl; + friend class BrokerProxyImpl; + friend class ConsoleImpl; + SchemaClassKey(SchemaClassKeyImpl* impl); + SchemaClassKeyImpl* impl; + }; + + /** + */ + class SchemaObjectClass { + public: + SchemaObjectClass(const char* package, const char* name); + SchemaObjectClass(const SchemaObjectClass& from); + ~SchemaObjectClass(); + void addProperty(const SchemaProperty* property); + void addStatistic(const SchemaStatistic* statistic); + void addMethod(const SchemaMethod* method); + + const SchemaClassKey* getClassKey() const; + int getPropertyCount() const; + int getStatisticCount() const; + int getMethodCount() const; + const SchemaProperty* getProperty(int idx) const; + const SchemaStatistic* getStatistic(int idx) const; + const SchemaMethod* getMethod(int idx) const; + + private: + friend struct SchemaObjectClassImpl; + friend class BrokerProxyImpl; + friend class AgentImpl; + SchemaObjectClass(SchemaObjectClassImpl* impl); + SchemaObjectClassImpl* impl; + }; + + /** + */ + class SchemaEventClass { + public: + SchemaEventClass(const char* package, const char* name, Severity severity); + SchemaEventClass(const SchemaEventClass& from); + ~SchemaEventClass(); + void addArgument(const SchemaArgument* argument); + void setDesc(const char* desc); + + const SchemaClassKey* getClassKey() const; + Severity getSeverity() const; + int getArgumentCount() const; + const SchemaArgument* getArgument(int idx) const; + + private: + friend struct SchemaEventClassImpl; + friend class BrokerProxyImpl; + friend class AgentImpl; + SchemaEventClass(SchemaEventClassImpl* impl); + SchemaEventClassImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/Typecode.h b/qpid/cpp/include/qmf/engine/Typecode.h new file mode 100644 index 0000000000..613f96a483 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Typecode.h @@ -0,0 +1,53 @@ +#ifndef _QmfEngineTypecode_ +#define _QmfEngineTypecode_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 qmf { +namespace engine { + + enum Typecode { + TYPE_UINT8 = 1, + TYPE_UINT16 = 2, + TYPE_UINT32 = 3, + TYPE_UINT64 = 4, + TYPE_SSTR = 6, + TYPE_LSTR = 7, + TYPE_ABSTIME = 8, + TYPE_DELTATIME = 9, + TYPE_REF = 10, + TYPE_BOOL = 11, + TYPE_FLOAT = 12, + TYPE_DOUBLE = 13, + TYPE_UUID = 14, + TYPE_MAP = 15, + TYPE_INT8 = 16, + TYPE_INT16 = 17, + TYPE_INT32 = 18, + TYPE_INT64 = 19, + TYPE_OBJECT = 20, + TYPE_LIST = 21, + TYPE_ARRAY = 22 + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/engine/Value.h b/qpid/cpp/include/qmf/engine/Value.h new file mode 100644 index 0000000000..5b45061b78 --- /dev/null +++ b/qpid/cpp/include/qmf/engine/Value.h @@ -0,0 +1,122 @@ +#ifndef _QmfEngineValue_ +#define _QmfEngineValue_ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <qmf/engine/ObjectId.h> +#include <qmf/engine/Typecode.h> + +namespace qmf { +namespace engine { + + class Object; + struct ValueImpl; + + class Value { + public: + // Value(); + Value(const Value& from); + Value(Typecode t, Typecode arrayType = TYPE_UINT8); + ~Value(); + + Typecode getType() const; + bool isNull() const; + void setNull(); + + bool isObjectId() const; + const ObjectId& asObjectId() const; + void setObjectId(const ObjectId& oid); + + bool isUint() const; + uint32_t asUint() const; + void setUint(uint32_t val); + + bool isInt() const; + int32_t asInt() const; + void setInt(int32_t val); + + bool isUint64() const; + uint64_t asUint64() const; + void setUint64(uint64_t val); + + bool isInt64() const; + int64_t asInt64() const; + void setInt64(int64_t val); + + bool isString() const; + const char* asString() const; + void setString(const char* val); + + bool isBool() const; + bool asBool() const; + void setBool(bool val); + + bool isFloat() const; + float asFloat() const; + void setFloat(float val); + + bool isDouble() const; + double asDouble() const; + void setDouble(double val); + + bool isUuid() const; + const uint8_t* asUuid() const; + void setUuid(const uint8_t* val); + + bool isObject() const; + const Object* asObject() const; + void setObject(Object* val); + + bool isMap() const; + bool keyInMap(const char* key) const; + Value* byKey(const char* key); + const Value* byKey(const char* key) const; + void deleteKey(const char* key); + void insert(const char* key, Value* val); + uint32_t keyCount() const; + const char* key(uint32_t idx) const; + + bool isList() const; + uint32_t listItemCount() const; + Value* listItem(uint32_t idx); + void appendToList(Value* val); + void deleteListItem(uint32_t idx); + + bool isArray() const; + Typecode arrayType() const; + uint32_t arrayItemCount() const; + Value* arrayItem(uint32_t idx); + void appendToArray(Value* val); + void deleteArrayItem(uint32_t idx); + + private: + friend struct ValueImpl; + friend class BrokerProxyImpl; + friend struct ObjectImpl; + friend struct EventImpl; + friend class AgentImpl; + Value(ValueImpl* impl); + ValueImpl* impl; + }; +} +} + +#endif + diff --git a/qpid/cpp/include/qmf/exceptions.h b/qpid/cpp/include/qmf/exceptions.h new file mode 100644 index 0000000000..c7ffa68ce2 --- /dev/null +++ b/qpid/cpp/include/qmf/exceptions.h @@ -0,0 +1,59 @@ +#ifndef QMF_EXCEPTIONS_H +#define QMF_EXCEPTIONS_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 "qmf/ImportExport.h" +#include "qpid/types/Exception.h" +#include "qpid/types/Variant.h" + +namespace qmf { + +/** \ingroup qmf + */ + + struct QMF_CLASS_EXTERN QmfException : public qpid::types::Exception { + QMF_EXTERN QmfException(const std::string& msg); + QMF_EXTERN virtual ~QmfException() throw(); + + qpid::types::Variant::Map detail; + }; + + struct QMF_CLASS_EXTERN KeyNotFound : public QmfException { + QMF_EXTERN KeyNotFound(const std::string& msg); + QMF_EXTERN virtual ~KeyNotFound() throw(); + }; + + struct QMF_CLASS_EXTERN IndexOutOfRange : public QmfException { + QMF_EXTERN IndexOutOfRange(); + QMF_EXTERN virtual ~IndexOutOfRange() throw(); + }; + + struct QMF_CLASS_EXTERN OperationTimedOut : public QmfException { + QMF_EXTERN OperationTimedOut(); + QMF_EXTERN virtual ~OperationTimedOut() throw(); + }; + +} + +#endif + diff --git a/qpid/cpp/include/qpid/Address.h b/qpid/cpp/include/qpid/Address.h new file mode 100755 index 0000000000..f5b19d0532 --- /dev/null +++ b/qpid/cpp/include/qpid/Address.h @@ -0,0 +1,55 @@ +#ifndef QPID_ADDRESS_H +#define QPID_ADDRESS_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 "qpid/CommonImportExport.h" +#include <iosfwd> +#include <string> + +namespace qpid { +namespace client { struct ConnectionSettings; } + + +/** + * Contains the protocol address of an AMQP broker. + */ +struct Address { +public: + static const std::string TCP; // Default TCP protocol tag. + static const uint16_t AMQP_PORT=5672; // Default AMQP port. + + QPID_COMMON_INLINE_EXTERN explicit Address( + const std::string& protocol_=std::string(), + const std::string& host_=std::string(), + uint16_t port_=0 + ) : protocol(protocol_), host(host_), port(port_) {} + + std::string protocol; + std::string host; + uint16_t port; +}; + +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const Address& addr); +QPID_COMMON_EXTERN bool operator==(const Address& x, const Address& y); + +} // namespace qpid + +#endif /*!QPID_ADDRESS_H*/ diff --git a/qpid/cpp/include/qpid/CommonImportExport.h b/qpid/cpp/include/qpid/CommonImportExport.h new file mode 100644 index 0000000000..dd2b900b73 --- /dev/null +++ b/qpid/cpp/include/qpid/CommonImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_COMMON_IMPORT_EXPORT_H +#define QPID_COMMON_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. + */ + +#include "qpid/ImportExport.h" + +#if defined(COMMON_EXPORT) || defined (qpidcommon_EXPORTS) +# define QPID_COMMON_EXTERN QPID_EXPORT +# define QPID_COMMON_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_COMMON_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_COMMON_EXTERN QPID_IMPORT +# define QPID_COMMON_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_COMMON_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif diff --git a/qpid/cpp/include/qpid/Exception.h b/qpid/cpp/include/qpid/Exception.h new file mode 100644 index 0000000000..cbd175214d --- /dev/null +++ b/qpid/cpp/include/qpid/Exception.h @@ -0,0 +1,91 @@ +#ifndef _Exception_ +#define _Exception_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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/constants.h" +#include "qpid/framing/enum.h" +#include "qpid/sys/StrError.h" +#include "qpid/CommonImportExport.h" +#include <string> +#include <errno.h> + +namespace qpid +{ + +/** + * Base class for Qpid runtime exceptions. + */ +class QPID_COMMON_CLASS_EXTERN Exception : public std::exception +{ + public: + QPID_COMMON_EXTERN explicit Exception(const std::string& message=std::string()) throw(); + QPID_COMMON_EXTERN virtual ~Exception() throw(); + QPID_COMMON_EXTERN virtual const char* what() const throw(); // prefix: message + QPID_COMMON_EXTERN virtual std::string getMessage() const; // Unprefixed message + QPID_COMMON_EXTERN virtual std::string getPrefix() const; // Prefix + + private: + std::string message; + mutable std::string whatStr; +}; + +/** Exception that includes an errno message. */ +struct QPID_COMMON_CLASS_EXTERN ErrnoException : public Exception { + ErrnoException(const std::string& msg, int err) : Exception(msg+": "+qpid::sys::strError(err)) {} + ErrnoException(const std::string& msg) : Exception(msg+": "+qpid::sys::strError(errno)) {} +}; + +struct QPID_COMMON_CLASS_EXTERN SessionException : public Exception { + const framing::execution::ErrorCode code; + SessionException(framing::execution::ErrorCode code_, const std::string& message) + : Exception(message), code(code_) {} +}; + +struct QPID_COMMON_CLASS_EXTERN ChannelException : public Exception { + const framing::session::DetachCode code; + ChannelException(framing::session::DetachCode _code, const std::string& message) + : Exception(message), code(_code) {} +}; + +struct QPID_COMMON_CLASS_EXTERN ConnectionException : public Exception { + const framing::connection::CloseCode code; + ConnectionException(framing::connection::CloseCode _code, const std::string& message) + : Exception(message), code(_code) {} +}; + +struct QPID_COMMON_CLASS_EXTERN ClosedException : public Exception { + QPID_COMMON_EXTERN ClosedException(const std::string& msg=std::string()); + QPID_COMMON_EXTERN std::string getPrefix() const; +}; + +/** + * Exception representing transport failure + */ +struct TransportFailure : public Exception { + TransportFailure(const std::string& msg=std::string()) : Exception(msg) {} +}; + +} // namespace qpid + +#endif /*!_Exception_*/ diff --git a/qpid/cpp/include/qpid/ImportExport.h b/qpid/cpp/include/qpid/ImportExport.h new file mode 100644 index 0000000000..e62399faf7 --- /dev/null +++ b/qpid/cpp/include/qpid/ImportExport.h @@ -0,0 +1,71 @@ +#ifndef QPID_IMPORTEXPORT_H +#define QPID_IMPORTEXPORT_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. + */ + +// +// This header file defines the following macros for the control of library/DLL +// import and export: +// +// QPID_EXPORT - Export declaration for Methods +// QPID_CLASS_EXPORT - Export declaration for Classes +// QPID_INLINE_EXPORT - Export declaration for Inline methods +// +// QPID_IMPORT - Import declaration for Methods +// QPID_CLASS_IMPORT - Import declaration for Classes +// QPID_INLINE_IMPORT - Import declaration for Inline methods +// + +#if defined(WIN32) && !defined(QPID_DECLARE_STATIC) + // + // Import and Export definitions for Windows: + // +# define QPID_EXPORT __declspec(dllexport) +# define QPID_IMPORT __declspec(dllimport) +# ifdef _MSC_VER + // + // Specific to the Microsoft compiler: + // +# define QPID_CLASS_EXPORT +# define QPID_CLASS_IMPORT +# define QPID_INLINE_EXPORT QPID_EXPORT +# define QPID_INLINE_IMPORT QPID_IMPORT +# else + // + // Specific to non-Microsoft compilers (mingw32): + // +# define QPID_CLASS_EXPORT QPID_EXPORT +# define QPID_CLASS_IMPORT QPID_IMPORT +# define QPID_INLINE_EXPORT +# define QPID_INLINE_IMPORT +# endif +#else + // + // Non-Windows (Linux, etc.) definitions: + // +# define QPID_EXPORT +# define QPID_IMPORT +# define QPID_CLASS_EXPORT +# define QPID_CLASS_IMPORT +# define QPID_INLINE_EXPORT +# define QPID_INLINE_IMPORT +#endif + +#endif /*!QPID_IMPORTEXPORT_H*/ diff --git a/qpid/cpp/include/qpid/InlineAllocator.h b/qpid/cpp/include/qpid/InlineAllocator.h new file mode 100644 index 0000000000..2502545dcb --- /dev/null +++ b/qpid/cpp/include/qpid/InlineAllocator.h @@ -0,0 +1,101 @@ +#ifndef QPID_INLINEALLOCATOR_H +#define QPID_INLINEALLOCATOR_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 <assert.h> +#include <boost/type_traits/type_with_alignment.hpp> +#include <boost/type_traits/alignment_of.hpp> + +namespace qpid { + +template <typename RequestedType, typename InlineType, typename BaseAllocator, size_t Max> +struct InlineRebind; + + +/** + * An allocator that has inline storage for up to Max objects + * of type BaseAllocator::value_type. + */ +template <class BaseAllocator, size_t Max> +class InlineAllocator : public BaseAllocator { + public: + typedef typename BaseAllocator::pointer pointer; + typedef typename BaseAllocator::size_type size_type; + typedef typename BaseAllocator::value_type value_type; + + InlineAllocator() : allocated(false) {} + InlineAllocator(const InlineAllocator& x) : BaseAllocator(x), allocated(false) {} + + pointer allocate(size_type n) { + if (n <= Max && !allocated) { + allocated=true; + return reinterpret_cast<value_type*>(address()); + } + else + return BaseAllocator::allocate(n, 0); + } + + void deallocate(pointer p, size_type n) { + if (p == address()) { + assert(allocated); + allocated=false; + } + else + BaseAllocator::deallocate(p, n); + } + + template<typename T1> + struct rebind { + typedef typename InlineRebind<T1, value_type, BaseAllocator, Max>::other other; + }; + + private: + // POD object with alignment and size to hold Max value_types. + static const size_t ALIGNMENT=boost::alignment_of<value_type>::value; + typedef typename boost::type_with_alignment<ALIGNMENT>::type Aligner; + union Store { + Aligner aligner_; + char sizer_[sizeof(value_type)*Max]; + } store; + value_type* address() { return reinterpret_cast<value_type*>(&store); } + bool allocated; +}; + + +// Rebind: if RequestedType == InlineType, use the InlineAllocator, +// otherwise, use the BaseAllocator without any inlining. + +template <typename RequestedType, typename InlineType, typename BaseAllocator, size_t Max> +struct InlineRebind { + typedef typename BaseAllocator::template rebind<RequestedType>::other other; +}; + +template <typename T, typename BaseAllocator, size_t Max> +struct InlineRebind<T, T, BaseAllocator, Max> { + typedef typename qpid::InlineAllocator<BaseAllocator, Max> other; +}; + +} // namespace qpid + +#endif /*!QPID_INLINEALLOCATOR_H*/ diff --git a/qpid/cpp/include/qpid/InlineVector.h b/qpid/cpp/include/qpid/InlineVector.h new file mode 100644 index 0000000000..c55db295f3 --- /dev/null +++ b/qpid/cpp/include/qpid/InlineVector.h @@ -0,0 +1,68 @@ +#ifndef QPID_INLINEVECTOR_H +#define QPID_INLINEVECTOR_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/InlineAllocator.h" +#include <vector> + +namespace qpid { + +/** + * A vector that stores up to Max elements in inline storage, + * otherwise uses normal vector allocation. + * + * NOTE: depends on some non-standard but highly probably assumptions + * about how std::vector uses its allocator, they are true for g++. + * - default constructor does not allocate. + * - reserve(N) does not allocate more than N elements. + * - vector never re-allocates when size() < capacity() + */ +template <class T, size_t Max, class Alloc=std::allocator<T> > +class InlineVector : public std::vector<T, InlineAllocator<Alloc, Max> > +{ + typedef std::vector<T, InlineAllocator<Alloc, Max> > Base; + public: + typedef typename Base::allocator_type allocator_type; + typedef typename Base::value_type value_type; + typedef typename Base::size_type size_type; + + explicit InlineVector(const allocator_type& a=allocator_type()) : Base(a) { + this->reserve(Max); + } + + explicit InlineVector(size_type n, const value_type& x = value_type(), + const allocator_type& a=allocator_type()) : Base(a) + { + this->reserve(std::max(n, Max)); + this->insert(this->end(), n, x); + } + + InlineVector(const InlineVector& x) : Base() { + this->reserve(std::max(x.size(), Max)); + *this = x; + } +}; + +} // namespace qpid + +#endif /*!QPID_INLINEVECTOR_H*/ diff --git a/qpid/cpp/include/qpid/Msg.h b/qpid/cpp/include/qpid/Msg.h new file mode 100644 index 0000000000..e1837c29e5 --- /dev/null +++ b/qpid/cpp/include/qpid/Msg.h @@ -0,0 +1,78 @@ +#ifndef QPID_MSG_H +#define QPID_MSG_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 <sstream> +#include <iostream> + +namespace qpid { + +/** A simple wrapper for std::ostringstream that allows + * in place construction of a message and automatic conversion + * to string. + * E.g. + *@code + * void foo(const std::string&); + * foo(Msg() << "hello " << 32); + *@endcode + * Will construct the string "hello 32" and pass it to foo() + */ +struct Msg { + std::ostringstream os; + Msg() {} + Msg(const Msg& m) : os(m.str()) {} + std::string str() const { return os.str(); } + operator std::string() const { return str(); } + + Msg& operator<<(long n) { os << n; return *this; } + Msg& operator<<(unsigned long n) { os << n; return *this; } + Msg& operator<<(bool n) { os << n; return *this; } + Msg& operator<<(short n) { os << n; return *this; } + Msg& operator<<(unsigned short n) { os << n; return *this; } + Msg& operator<<(int n) { os << n; return *this; } + Msg& operator<<(unsigned int n) { os << n; return *this; } +#ifdef _GLIBCXX_USE_LONG_LONG + Msg& operator<<(long long n) { os << n; return *this; } + Msg& operator<<(unsigned long long n) { os << n; return *this; } +#endif + Msg& operator<<(double n) { os << n; return *this; } + Msg& operator<<(float n) { os << n; return *this; } + Msg& operator<<(long double n) { os << n; return *this; } + + template <class T> Msg& operator<<(const T& t) { os <<t; return *this; } +}; + + + +inline std::ostream& operator<<(std::ostream& o, const Msg& m) { + return o << m.str(); +} + +/** Construct a message using operator << and append (file:line) */ +#define QUOTE_(x) #x +#define QUOTE(x) QUOTE_(x) +#define QPID_MSG(message) (::qpid::Msg() << message << " (" __FILE__ ":" QUOTE(__LINE__) ")") + +} // namespace qpid + +#endif /*!QPID_MSG_H*/ diff --git a/qpid/cpp/include/qpid/Options.h b/qpid/cpp/include/qpid/Options.h new file mode 100644 index 0000000000..63d91c2d72 --- /dev/null +++ b/qpid/cpp/include/qpid/Options.h @@ -0,0 +1,177 @@ +#ifndef QPID_COMMONOPTIONS_H +#define QPID_COMMONOPTIONS_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" + +// Disable warnings triggered by boost. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4251 4275) +#endif + +#include <boost/program_options.hpp> +#include <boost/format.hpp> + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#include <sstream> +#include <iterator> +#include <algorithm> +#include <string> +#include "qpid/CommonImportExport.h" + +namespace qpid { +namespace po=boost::program_options; + + + +///@internal +QPID_COMMON_EXTERN std::string prettyArg(const std::string&, const std::string&); + +/** @internal Normally only constructed by optValue() */ +template <class T> +class OptionValue : public po::typed_value<T> { + public: + OptionValue(T& value, const std::string& arg) + : po::typed_value<T>(&value), argName(arg) {} + std::string name() const { return argName; } + + private: + std::string argName; +}; + + +/** Create an option value. + * name, value appear after the option name in help like this: + * <name> (=<value>) + * T must support operator <<. + *@see Options for example of use. + */ +template<class T> +po::value_semantic* optValue(T& value, const char* name) { + std::string valstr(boost::lexical_cast<std::string>(value)); + return new OptionValue<T>(value, prettyArg(name, valstr)); +} + +/** Create a vector value. Multiple occurences of the option are + * accumulated into the vector + */ +template <class T> +po::value_semantic* optValue(std::vector<T>& value, const char* name) { + using namespace std; + ostringstream os; + copy(value.begin(), value.end(), ostream_iterator<T>(os, " ")); + string val=os.str(); + if (!val.empty()) + val.erase(val.end()-1); // Remove trailing " " + return (new OptionValue<vector<T> >(value, prettyArg(name, val))); +} + +/** Create a boolean switch value. Presence of the option sets the value. */ +inline po::value_semantic* optValue(bool& value) { return po::bool_switch(&value); } + +/** + * Base class for options. + * Example of use: + @code + struct MySubOptions : public Options { + int x; + string y; + MySubOptions() : Options("Sub options") { + addOptions() + ("x", optValue(x,"XUNIT"), "Option X") + ("y", optValue(y, "YUNIT"), "Option Y"); + } + }; + + struct MyOptions : public Options { + bool z; + vector<string> foo; + MySubOptions subOptions; + MyOptions() : Options("My Options") { + addOptions() + ("z", boolSwitch(z), "Option Z") + ("foo", optValue(foo), "Multiple option foo"); + add(subOptions); + } + + main(int argc, char** argv) { + Options opts; + opts.parse(argc, char** argv); + // Use values + dosomething(opts.subOptions.x); + if (error) + cout << opts << end; // Help message. + } + + @endcode + */ + + + + +struct Options : public po::options_description { + + struct Exception : public qpid::Exception { + Exception(const std::string& msg) : qpid::Exception(msg) {} + }; + + QPID_COMMON_EXTERN Options(const std::string& name=std::string()); + + /** + * Parses options from argc/argv, environment variables and config file. + * Note the filename argument can reference an options variable that + * is updated by argc/argv or environment variable parsing. + */ + QPID_COMMON_EXTERN void parse(int argc, char const* const* argv, + const std::string& configfile=std::string(), + bool allowUnknown = false); + + + boost::program_options::options_description_easy_init addOptions() { + return add_options(); + } +}; + + + +/** + * Standard options for configuration + */ +struct CommonOptions : public Options { + QPID_COMMON_EXTERN CommonOptions(const std::string& name=std::string(), + const std::string& configfile=std::string()); + bool help; + bool version; + std::string config; +}; + + + + +} // namespace qpid + +#endif /*!QPID_COMMONOPTIONS_H*/ diff --git a/qpid/cpp/include/qpid/RangeSet.h b/qpid/cpp/include/qpid/RangeSet.h new file mode 100644 index 0000000000..36991fd784 --- /dev/null +++ b/qpid/cpp/include/qpid/RangeSet.h @@ -0,0 +1,330 @@ +#ifndef QPID_RANGESET_H +#define QPID_RANGESET_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/InlineVector.h" +#include <boost/iterator/iterator_facade.hpp> +#include <boost/operators.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <numeric> + +namespace qpid { + +/** A range of values, used in RangeSet. + * Range(begin, end) includes begin but excludes end. + * Range::makeClosed(first,last) includes both first and last. + */ +template <class T> +class Range { + public: + static Range makeClosed(const T& first, T last) { return Range(first, ++last); } + + Range() : begin_(), end_() {} + explicit Range(const T& t) : begin_(t), end_(t) { ++end_; } + Range(const T& b, const T& e) : begin_(b), end_(e) { assert(b <= e); } + + T begin() const { return begin_; } + /** End of _open_ range, i.e. !contains(end()) */ + T end() const { return end_; } + + T first() const { assert(!empty()); return begin_; } + /** Last in closed range, i.e. contains(end()) */ + T last() const { assert(!empty()); T ret=end_; return --ret; } + + void begin(const T& t) { begin_ = t; } + void end(const T& t) { end_ = t; } + size_t size() const { return end_ - begin_; } + bool empty() const { return begin_ == end_; } + + bool contains(const T& x) const { return begin_ <= x && x < end_; } + bool contains(const Range& r) const { return begin_ <= r.begin_ && r.end_ <= end_; } + bool strictContains(const Range& r) const { return begin_ < r.begin_ && r.end_ < end_; } + + bool operator==(const Range& x) { return begin_ == x.begin_ && end_== x.end_; } + + bool operator<(const T& t) const { return end_ < t; } + bool operator<(const Range<T>& r) const { return end_ < r.begin_; } + + /** touching ranges can be merged into a single range. */ + bool touching(const Range& r) const { + return std::max(begin_, r.begin_) <= std::min(end_, r.end_); + } + + /** @pre touching */ + void merge(const Range& r) { + assert(touching(r)); + begin_ = std::min(begin_, r.begin_); + end_ = std::max(end_, r.end_); + } + + operator bool() const { return !empty(); } + + template <class S> void serialize(S& s) { s(begin_)(end_); } + + private: + T begin_, end_; +}; + + +/** + * A set implemented as a list of [begin, end) ranges. + * T must be LessThanComparable and Incrementable. + * RangeSet only provides const iterators. + */ +template <class T> +class RangeSet + : boost::additive1<RangeSet<T>, + boost::additive2<RangeSet<T>, Range<T>, + boost::additive2<RangeSet<T>, T> > > +{ + typedef InlineVector<Range<T>, 3> Ranges; // TODO aconway 2008-04-21: what's the optimial inlined value? + + public: + + class iterator : public boost::iterator_facade< + iterator, + const T, + boost::forward_traversal_tag> + { + public: + iterator() : ranges(), iter(), value() {} + + private: + typedef typename Ranges::const_iterator RangesIter; + iterator(const Ranges& r, const RangesIter& i, const T& t) + : ranges(&r), iter(i), value(t) {} + + void increment(); + bool equal(const iterator& i) const; + const T& dereference() const { return value; } + + const Ranges* ranges; + RangesIter iter; + T value; + + friend class RangeSet<T>; + friend class boost::iterator_core_access; + }; + + typedef iterator const_iterator; + + RangeSet() {} + explicit RangeSet(const Range<T>& r) { *this += r; } + RangeSet(const T& a, const T& b) { *this += Range<T>(a,b); } + + bool contiguous() const { return ranges.size() <= 1; } + + bool contains(const T& t) const; + bool contains(const Range<T>&) const; + + /**@pre contiguous() */ + Range<T> toRange() const; + + bool operator==(const RangeSet<T>&) const; + + void addRange (const Range<T>&); + void addSet (const RangeSet<T>&); + + RangeSet<T>& operator+=(const T& t) { return *this += Range<T>(t); } + RangeSet<T>& operator+=(const Range<T>& r) { addRange(r); return *this; } + RangeSet<T>& operator+=(const RangeSet<T>& s) { addSet(s); return *this; } + + void removeRange (const Range<T>&); + void removeSet (const RangeSet<T>&); + + RangeSet<T>& operator-=(const T& t) { return *this -= Range<T>(t); } + RangeSet<T>& operator-=(const Range<T>& r) { removeRange(r); return *this; } + RangeSet<T>& operator-=(const RangeSet<T>& s) { removeSet(s); return *this; } + + T front() const { return ranges.front().begin(); } + T back() const { return ranges.back().end(); } + + // Iterate over elements in the set. + iterator begin() const; + iterator end() const; + + // Iterate over ranges in the set. + typedef typename Ranges::const_iterator RangeIterator; + RangeIterator rangesBegin() const { return ranges.begin(); } + RangeIterator rangesEnd() const { return ranges.end(); } + size_t rangesSize() const { return ranges.size(); } + + // The difference between the start and end of this range set + uint32_t span() const; + + size_t size() const; + bool empty() const { return ranges.empty(); } + void clear() { ranges.clear(); } + + /** Return the largest contiguous range containing x. + * Returns the empty range [x,x) if x is not in the set. + */ + Range<T> rangeContaining(const T&) const; + + template <class S> void serialize(S& s) { s.split(*this); s(ranges.begin(), ranges.end()); } + template <class S> void encode(S& s) const { s(uint16_t(ranges.size()*sizeof(Range<T>))); } + template <class S> void decode(S& s) { uint16_t sz; s(sz); ranges.resize(sz/sizeof(Range<T>)); } + + private: + static size_t accumulateSize(size_t s, const Range<T>& r) { return s+r.size(); } + Ranges ranges; + + template <class U> friend std::ostream& operator<<(std::ostream& o, const RangeSet<U>& r); + + friend class iterator; +}; + +template <class T> +std::ostream& operator<<(std::ostream& o, const Range<T>& r) { + return o << "[" << r.begin() << "," << r.end() << ")"; +} + +template <class T> +std::ostream& operator<<(std::ostream& o, const RangeSet<T>& rs) { + std::ostream_iterator<Range<T> > i(o, " "); + o << "{ "; + std::copy(rs.ranges.begin(), rs.ranges.end(), i); + return o << "}"; +} + +template <class T> +bool RangeSet<T>::contains(const T& t) const { + typename Ranges::const_iterator i = + std::lower_bound(ranges.begin(), ranges.end(), Range<T>(t)); + return i != ranges.end() && i->contains(t); +} + +template <class T> +bool RangeSet<T>::contains(const Range<T>& r) const { + typename Ranges::const_iterator i = + std::lower_bound(ranges.begin(), ranges.end(), r); + return i != ranges.end() && i->contains(r); +} + +template <class T> void RangeSet<T>::addRange(const Range<T>& r) { + if (r.empty()) return; + typename Ranges::iterator i = + std::lower_bound(ranges.begin(), ranges.end(), r); + if (i == ranges.end() || !i->touching(r)) + ranges.insert(i, r); + else { + i->merge(r); + typename Ranges::iterator j = i; + if (++j != ranges.end() && i->touching(*j)) { + i->merge(*j); + ranges.erase(j); + } + } +} + + +template <class T> void RangeSet<T>::addSet(const RangeSet<T>& s) { + typedef RangeSet<T>& (RangeSet<T>::*RangeSetRangeOp)(const Range<T>&); + std::for_each(s.ranges.begin(), s.ranges.end(), + boost::bind((RangeSetRangeOp)&RangeSet<T>::operator+=, this, _1)); +} + +template <class T> void RangeSet<T>::removeRange(const Range<T>& r) { + if (r.empty()) return; + typename Ranges::iterator i,j; + i = std::lower_bound(ranges.begin(), ranges.end(), r); + if (i == ranges.end() || i->begin() >= r.end()) + return; // Outside of set + if (*i == r) // Erase i + ranges.erase(i); + else if (i->strictContains(r)) { // Split i + Range<T> i1(i->begin(), r.begin()); + Range<T> i2(r.end(), i->end()); + *i = i2; + ranges.insert(i, i1); + } else { + if (i->begin() < r.begin()) { // Truncate i + i->end(r.begin()); + ++i; + } + for (j = i; j != ranges.end() && r.contains(*j); ++j) + ; // Ranges to erase. + if (j != ranges.end() && r.end() > j->begin()) + j->begin(r.end()); // Truncate j + ranges.erase(i,j); + } +} + +template <class T> void RangeSet<T>::removeSet(const RangeSet<T>& r) { + std::for_each( + r.ranges.begin(), r.ranges.end(), + boost::bind(&RangeSet<T>::removeRange, this, _1)); +} + +template <class T> Range<T> RangeSet<T>::toRange() const { + assert(contiguous()); + return empty() ? Range<T>() : ranges.front(); +} + +template <class T> void RangeSet<T>::iterator::increment() { + assert(ranges && iter != ranges->end()); + if (!iter->contains(++value)) { + ++iter; + if (iter == ranges->end()) + *this=iterator(); // end() iterator + else + value=iter->begin(); + } +} + +template <class T> bool RangeSet<T>::operator==(const RangeSet<T>& r) const { + return ranges.size() == r.ranges.size() && std::equal(ranges.begin(), ranges.end(), r.ranges.begin()); +} + +template <class T> typename RangeSet<T>::iterator RangeSet<T>::begin() const { + return empty() ? end() : iterator(ranges, ranges.begin(), front()); +} + +template <class T> typename RangeSet<T>::iterator RangeSet<T>::end() const { + return iterator(); +} + +template <class T> bool RangeSet<T>::iterator::equal(const iterator& i) const { + return ranges==i.ranges && (ranges==0 || value==i.value); +} + +template <class T> Range<T> RangeSet<T>::rangeContaining(const T& t) const { + typename Ranges::const_iterator i = + std::lower_bound(ranges.begin(), ranges.end(), Range<T>(t)); + return (i != ranges.end() && i->contains(t)) ? *i : Range<T>(t,t); +} + +template <class T> uint32_t RangeSet<T>::span() const { + if (ranges.empty()) return 0; + return ranges.back().last() - ranges.front().first(); +} + +template <class T> size_t RangeSet<T>::size() const { + return std::accumulate(rangesBegin(), rangesEnd(), 0, &RangeSet<T>::accumulateSize); +} + +} // namespace qpid + + +#endif /*!QPID_RANGESET_H*/ diff --git a/qpid/cpp/include/qpid/SessionId.h b/qpid/cpp/include/qpid/SessionId.h new file mode 100644 index 0000000000..e18b360999 --- /dev/null +++ b/qpid/cpp/include/qpid/SessionId.h @@ -0,0 +1,60 @@ +#ifndef QPID_SESSIONID_H +#define QPID_SESSIONID_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/operators.hpp> +#include <string> +#include <qpid/CommonImportExport.h> + +namespace qpid { + +/** Identifier for a session. + * There are two parts to a session identifier: + * + * getUserId() returns the authentication principal associated with + * the session's connection. + * + * getName() returns the session name. + * + * The name must be unique among sessions with the same authentication + * principal. + */ +class SessionId : boost::totally_ordered1<SessionId> { + std::string userId; + std::string name; + public: + QPID_COMMON_EXTERN SessionId(const std::string& userId=std::string(), const std::string& name=std::string()); + std::string getUserId() const { return userId; } + std::string getName() const { return name; } + QPID_COMMON_EXTERN bool operator<(const SessionId&) const ; + QPID_COMMON_EXTERN bool operator==(const SessionId& id) const; + // Convert to a string + QPID_COMMON_EXTERN std::string str() const; +}; + +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionId&); + + +} // namespace qpid + +#endif /*!QPID_SESSIONID_H*/ diff --git a/qpid/cpp/include/qpid/Url.h b/qpid/cpp/include/qpid/Url.h new file mode 100644 index 0000000000..915b08ac5f --- /dev/null +++ b/qpid/cpp/include/qpid/Url.h @@ -0,0 +1,99 @@ +#ifndef QPID_URL_H +#define QPID_URL_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/Address.h" +#include "qpid/Exception.h" +#include <string> +#include <vector> +#include <new> +#include <ostream> +#include "qpid/CommonImportExport.h" + +namespace qpid { + +/** An AMQP URL contains a list of addresses */ +struct Url : public std::vector<Address> { + + /** Url with the hostname as returned by gethostname(2) */ + QPID_COMMON_EXTERN static Url getHostNameUrl(uint16_t port); + + /** Url with local IP address(es), may be more than one address + * on a multi-homed host. */ + QPID_COMMON_EXTERN static Url getIpAddressesUrl(uint16_t port); + + struct Invalid : public Exception { Invalid(const std::string& s); }; + + /** Convert to string form. */ + QPID_COMMON_EXTERN std::string str() const; + + /** Empty URL. */ + Url() {} + + /** URL containing a single address */ + explicit Url(const Address& addr) { push_back(addr); } + + /** Parse url, throw Invalid if invalid. */ + explicit Url(const std::string& url) { parse(url.c_str()); } + + /** Parse url, throw Invalid if invalid. */ + explicit Url(const char* url) { parse(url); } + + Url& operator=(const char* s) { parse(s); return *this; } + Url& operator=(const std::string& s) { parse(s); return *this; } + + /** Throw Invalid if the URL does not contain any addresses. */ + QPID_COMMON_EXTERN void throwIfEmpty() const; + + /** Replace contents with parsed url + *@exception Invalid if the url is invalid. + */ + QPID_COMMON_EXTERN void parse(const char* url); + QPID_COMMON_INLINE_EXTERN void parse(const std::string& url) { parse(url.c_str()); } + + /** Replace contesnts with parsed URL. Replace with empty URL if invalid. */ + QPID_COMMON_EXTERN void parseNoThrow(const char* url); + + /** Add a protocol tag to be recognzed in URLs. + * Only for use by protcol plug-in initializers. + */ + QPID_COMMON_EXTERN static void addProtocol(const std::string& tag); + + QPID_COMMON_EXTERN void setUser(const std::string&); + QPID_COMMON_EXTERN void setPass(const std::string&); + QPID_COMMON_EXTERN std::string getUser() const; + QPID_COMMON_EXTERN std::string getPass() const; + + private: + mutable std::string cache; // cache string form for efficiency. + std::string user, pass; + + friend class UrlParser; +}; + +inline bool operator==(const Url& a, const Url& b) { return a.str()==b.str(); } +inline bool operator!=(const Url& a, const Url& b) { return a.str()!=b.str(); } + +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const Url& url); +QPID_COMMON_EXTERN std::istream& operator>>(std::istream& is, Url& url); + +} // namespace qpid + +#endif /*!QPID_URL_H*/ diff --git a/qpid/cpp/include/qpid/agent/ManagementAgent.h b/qpid/cpp/include/qpid/agent/ManagementAgent.h new file mode 100644 index 0000000000..e2451244c1 --- /dev/null +++ b/qpid/cpp/include/qpid/agent/ManagementAgent.h @@ -0,0 +1,205 @@ +#ifndef _qpid_agent_ManagementAgent_ +#define _qpid_agent_ManagementAgent_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT 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/agent/QmfAgentImportExport.h" +#include "qpid/management/ManagementObject.h" +#include "qpid/management/ManagementEvent.h" +#include "qpid/management/Manageable.h" +#include "qpid/management/ConnectionSettings.h" + +namespace qpid { +namespace management { + +class Notifyable { +public: + virtual ~Notifyable() {} + virtual void notify() = 0; +}; + +class ManagementAgent +{ + public: + + class Singleton { + public: + QMF_AGENT_EXTERN Singleton(bool disableManagement = false); + QMF_AGENT_EXTERN ~Singleton(); + QMF_AGENT_EXTERN static ManagementAgent* getInstance(); + }; + + typedef enum { + SEV_EMERG = 0, + SEV_ALERT = 1, + SEV_CRIT = 2, + SEV_ERROR = 3, + SEV_WARN = 4, + SEV_NOTE = 5, + SEV_INFO = 6, + SEV_DEBUG = 7, + SEV_DEFAULT = 8 + } severity_t; + + ManagementAgent() {} + virtual ~ManagementAgent() {} + + virtual int getMaxThreads() = 0; + + // Set the name of the agent + // + // vendor - Vendor name or domain (i.e. "apache.org") + // product - Product name (i.e. "qpid") + // instance - A unique identifier for this instance of the agent. + // If empty, the agent will create a GUID for the instance. + // Note: the ":" character is reserved - do no use it in the vendor or product name. + // + virtual void setName(const std::string& vendor, + const std::string& product, + const std::string& instance="") = 0; + + // Retrieve the name of the agent as assigned by setName() + // + virtual void getName(std::string& vendor, + std::string& product, + std::string& instance) = 0; + + // Obtain the fully qualified name of the agent + // + virtual const std::string& getAddress() = 0; + + // Connect to a management broker + // + // brokerHost - Hostname or IP address (dotted-quad) of broker. + // + // brokerPort - TCP port of broker. + // + // intervalSeconds - The interval (in seconds) that this agent shall use + // between broadcast updates to the broker. + // + // useExternalThread - If true, the thread of control used for callbacks + // must be supplied by the user of the object (via the + // pollCallbacks method). + // + // If false, callbacks shall be invoked on the management + // agent's thread. In this case, the callback implementations + // MUST be thread safe. + // + // storeFile - File where this process has read and write access. This + // file shall be used to store persistent state. + // + virtual void init(const std::string& brokerHost = "localhost", + uint16_t brokerPort = 5672, + uint16_t intervalSeconds = 10, + bool useExternalThread = false, + const std::string& storeFile = "", + const std::string& uid = "guest", + const std::string& pwd = "guest", + const std::string& mech = "PLAIN", + const std::string& proto = "tcp") = 0; + + virtual void init(const management::ConnectionSettings& settings, + uint16_t intervalSeconds = 10, + bool useExternalThread = false, + const std::string& storeFile = "") = 0; + + + // Register a schema with the management agent. This is normally called by the + // package initializer generated by the management code generator. + // + virtual void + registerClass(const std::string& packageName, + const std::string& className, + uint8_t* md5Sum, + management::ManagementObject::writeSchemaCall_t schemaCall) = 0; + + virtual void + registerEvent(const std::string& packageName, + const std::string& eventName, + uint8_t* md5Sum, + management::ManagementEvent::writeSchemaCall_t schemaCall) = 0; + + // Add a management object to the agent. Once added, this object shall be visible + // in the greater management context. + // + // Please note that ManagementObject instances are not explicitly deleted from + // the management agent. When the core object represented by a management object + // is deleted, the "resourceDestroy" method on the management object must be called. + // It will then be reclaimed in due course by the management agent. + // + // Once a ManagementObject instance is added to the agent, the agent then owns the + // instance. The caller MUST NOT free the resources of the instance at any time. + // When it is no longer needed, invoke its "resourceDestroy" method and discard the + // pointer. This allows the management agent to report the deletion of the object + // in an orderly way. + // + virtual ObjectId addObject(ManagementObject* objectPtr, uint64_t persistId = 0) = 0; + virtual ObjectId addObject(ManagementObject* objectPtr, + const std::string& key, + bool persistent = true) = 0; + + // + // + virtual void raiseEvent(const ManagementEvent& event, + severity_t severity = SEV_DEFAULT) = 0; + + // If "useExternalThread" was set to true in init, this method must + // be called to provide a thread for any pending method calls that have arrived. + // The method calls for ManagementObject instances shall be invoked synchronously + // during the execution of this method. + // + // callLimit may optionally be used to limit the number of callbacks invoked. + // if 0, no limit is imposed. + // + // The return value is the number of callbacks that remain queued after this + // call is complete. It can be used to determine whether or not further calls + // to pollCallbacks are necessary to clear the backlog. If callLimit is zero, + // the return value will also be zero. + // + virtual uint32_t pollCallbacks(uint32_t callLimit = 0) = 0; + + // In the "useExternalThread" scenario, there are three ways that an application can + // use to be notified that there is work to do. Of course the application may periodically + // call pollCallbacks if it wishes, but this will cause long latencies in the responses + // to method calls. + // + // The notification methods are: + // + // 1) Register a C-style callback by providing a pointer to a function + // 2) Register a C++-style callback by providing an object of a class that is derived + // from Notifyable + // 3) Call getSignalFd() to get a file descriptor that can be used in a select + // call. The file descriptor shall become readable when the agent has work to + // do. Note that this mechanism is specific to Posix-based operating environments. + // getSignalFd will probably not function correctly on Windows. + // + // If a callback is registered, the callback function will be called on the agent's + // thread. The callback function must perform no work other than to signal the application + // thread to call pollCallbacks. + // + typedef void (*cb_t)(void*); + virtual void setSignalCallback(cb_t callback, void* context) = 0; + virtual void setSignalCallback(Notifyable& notifyable) = 0; + virtual int getSignalFd() = 0; +}; + +}} + +#endif /*!_qpid_agent_ManagementAgent_*/ diff --git a/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h b/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h new file mode 100644 index 0000000000..3f923ac4b2 --- /dev/null +++ b/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h @@ -0,0 +1,35 @@ +#ifndef QMF_AGENT_IMPORT_EXPORT_H +#define QMF_AGENT_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. + */ + +#include "qpid/ImportExport.h" + +#if defined(QMF_EXPORT) || defined (qmf_EXPORTS) +# define QMF_AGENT_EXTERN QPID_EXPORT +# define QMF_AGENT_CLASS_EXTERN QPID_CLASS_EXPORT +# define QMF_AGENT_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QMF_AGENT_EXTERN QPID_IMPORT +# define QMF_AGENT_CLASS_EXTERN QPID_CLASS_IMPORT +# define QMF_AGENT_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif diff --git a/qpid/cpp/include/qpid/amqp_0_10/Codecs.h b/qpid/cpp/include/qpid/amqp_0_10/Codecs.h new file mode 100644 index 0000000000..08275402fc --- /dev/null +++ b/qpid/cpp/include/qpid/amqp_0_10/Codecs.h @@ -0,0 +1,77 @@ +#ifndef QPID_AMQP_0_10_CODECS_H +#define QPID_AMQP_0_10_CODECS_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/CommonImportExport.h" +#include "qpid/types/Variant.h" + +namespace qpid { +namespace framing { +class FieldTable; +} +namespace amqp_0_10 { +/** + * Codec for encoding/decoding a map of Variants using the AMQP 0-10 + * map encoding. + */ +class QPID_COMMON_EXTERN MapCodec +{ + public: + typedef qpid::types::Variant::Map ObjectType; + static void encode(const ObjectType&, std::string&); + static void decode(const std::string&, ObjectType&); + static size_t encodedSize(const ObjectType&); + static const std::string contentType; + private: +}; + +/** + * Codec for encoding/decoding a list of Variants using the AMQP 0-10 + * list encoding. + */ +class QPID_COMMON_EXTERN ListCodec +{ + public: + typedef qpid::types::Variant::List ObjectType; + static void encode(const ObjectType&, std::string&); + static void decode(const std::string&, ObjectType&); + static size_t encodedSize(const ObjectType&); + static const std::string contentType; + private: +}; + +/** + * @internal + * + * Conversion functions between qpid::types:Variant::Map and the + * deprecated qpid::framing::FieldTable. + * + */ +QPID_COMMON_EXTERN void translate(const qpid::types::Variant::Map& from, + qpid::framing::FieldTable& to); +QPID_COMMON_EXTERN void translate(const qpid::framing::FieldTable& from, + qpid::types::Variant::Map& to); + +}} // namespace qpid::amqp_0_10 + +#endif /*!QPID_AMQP_0_10_CODECS_H*/ diff --git a/qpid/cpp/include/qpid/client/AsyncSession.h b/qpid/cpp/include/qpid/client/AsyncSession.h new file mode 100644 index 0000000000..d91efeb4f1 --- /dev/null +++ b/qpid/cpp/include/qpid/client/AsyncSession.h @@ -0,0 +1,38 @@ +#ifndef QPID_CLIENT_ASYNCSESSION_H +#define QPID_CLIENT_ASYNCSESSION_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/client/AsyncSession_0_10.h" + +namespace qpid { +namespace client { + +/** + * AsyncSession is an alias for Session_0_10 + * + * \ingroup clientapi + */ +typedef AsyncSession_0_10 AsyncSession; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_ASYNCSESSION_H*/ diff --git a/qpid/cpp/include/qpid/client/ClientImportExport.h b/qpid/cpp/include/qpid/client/ClientImportExport.h new file mode 100644 index 0000000000..2a3a5a52e9 --- /dev/null +++ b/qpid/cpp/include/qpid/client/ClientImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_CLIENT_IMPORT_EXPORT_H +#define QPID_CLIENT_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. + */ + +#include "qpid/ImportExport.h" + +#if defined(CLIENT_EXPORT) || defined (qpidclient_EXPORTS) +# define QPID_CLIENT_EXTERN QPID_EXPORT +# define QPID_CLIENT_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_CLIENT_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_CLIENT_EXTERN QPID_IMPORT +# define QPID_CLIENT_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_CLIENT_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif diff --git a/qpid/cpp/include/qpid/client/Completion.h b/qpid/cpp/include/qpid/client/Completion.h new file mode 100644 index 0000000000..9546db9258 --- /dev/null +++ b/qpid/cpp/include/qpid/client/Completion.h @@ -0,0 +1,71 @@ +#ifndef QPID_CLIENT_COMPLETION_H +#define QPID_CLIENT_COMPLETION_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/client/Handle.h" +#include "qpid/client/ClientImportExport.h" +#include <string> + +namespace qpid { +namespace client { + +class CompletionImpl; +template <class T> class PrivateImplRef; + +/** + * Asynchronous commands that do not return a result will return a + * Completion. You can use the completion to wait for that specific + * command to complete. + * + *@see TypedResult + * + *\ingroup clientapi + */ +class QPID_CLIENT_CLASS_EXTERN Completion : public Handle<CompletionImpl> +{ +public: + QPID_CLIENT_EXTERN Completion(CompletionImpl* = 0); + QPID_CLIENT_EXTERN Completion(const Completion&); + QPID_CLIENT_EXTERN ~Completion(); + QPID_CLIENT_EXTERN Completion& operator=(const Completion&); + + /** Wait for the asynchronous command that returned this + *Completion to complete. + * + *@exception If the command returns an error. + */ + QPID_CLIENT_EXTERN void wait(); + QPID_CLIENT_EXTERN bool isComplete(); + + protected: + QPID_CLIENT_EXTERN std::string getResult(); + + private: + typedef CompletionImpl Impl; + friend class PrivateImplRef<Completion>; +}; + +}} + + +#endif /*!QPID_CLIENT_COMPLETION_H*/ diff --git a/qpid/cpp/include/qpid/client/Connection.h b/qpid/cpp/include/qpid/client/Connection.h new file mode 100644 index 0000000000..2477bf4800 --- /dev/null +++ b/qpid/cpp/include/qpid/client/Connection.h @@ -0,0 +1,228 @@ +#ifndef QPID_CLIENT_CONNECTION_H +#define QPID_CLIENT_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 <map> +#include <string> +#include "qpid/client/Session.h" +#include "qpid/client/ClientImportExport.h" +#include "qpid/client/ConnectionSettings.h" +#include "qpid/framing/ProtocolVersion.h" + +#include "boost/function.hpp" + +namespace qpid { + +struct Url; + +namespace client { + +class ConnectionImpl; + +/** + * Represents a connection to an AMQP broker. All communication is + * initiated by establishing a connection, then creating one or more + * Session objects using the connection. @see newSession() + * + * \ingroup clientapi + * + * Some methods use an AMQP 0-10 URL to specify connection parameters. + * This is defined in the AMQP 0-10 specification (http://jira.amqp.org/confluence/display/AMQP/AMQP+Specification). + * + * amqp_url = "amqp:" prot_addr_list + * prot_addr_list = [prot_addr ","]* prot_addr + * prot_addr = tcp_prot_addr | tls_prot_addr + * + * tcp_prot_addr = tcp_id tcp_addr + * tcp_id = "tcp:" | "" + * tcp_addr = [host [":" port] ] + * host = <as per http://www.ietf.org/rfc/rfc3986.txt> + * port = number]]> + * + */ + +class QPID_CLIENT_CLASS_EXTERN Connection +{ + framing::ProtocolVersion version; + + boost::function<void ()> failureCallback; + + + protected: + boost::shared_ptr<ConnectionImpl> impl; + + + public: + /** + * Creates a Connection object, but does not open the connection. + * @see open() + */ + QPID_CLIENT_EXTERN Connection(); + + /** + * Destroys a Connection object but does not close the connection if it + * was open. @see close() + */ + QPID_CLIENT_EXTERN ~Connection(); + + /** + * Opens a connection to a broker. + * + * @param host the host on which the broker is running. + * + * @param port the port on the which the broker is listening. + * + * @param uid the userid to connect with. + * + * @param pwd the password to connect with (currently SASL + * PLAIN is the only authentication method supported so this + * is sent in clear text). + * + * @param virtualhost the AMQP virtual host to use (virtual + * hosts, where implemented(!), provide namespace partitioning + * within a single broker). + */ + QPID_CLIENT_EXTERN void open(const std::string& host, int port = 5672, + const std::string& uid = "guest", + const std::string& pwd = "guest", + const std::string& virtualhost = "/", uint16_t maxFrameSize=65535); + + /** + * Opens a connection to a broker using a URL. + * If the URL contains multiple addresses, try each in turn + * till connection is successful. + * + * @url address of the broker to connect to. + * + * @param uid the userid to connect with. + * + * @param pwd the password to connect with (currently SASL + * PLAIN is the only authentication method supported so this + * is sent in clear text). + * + * @param virtualhost the AMQP virtual host to use (virtual + * hosts, where implemented(!), provide namespace partitioning + * within a single broker). + */ + QPID_CLIENT_EXTERN void open(const Url& url, + const std::string& uid = "guest", + const std::string& pwd = "guest", + const std::string& virtualhost = "/", uint16_t maxFrameSize=65535); + + /** + * Opens a connection to a broker using a URL. + * If the URL contains multiple addresses, try each in turn + * till connection is successful. + * + * @url address of the broker to connect to. + * + * @param settings used for any settings not provided by the URL. + * Settings provided by the url (e.g. host, port) are ignored. + */ + QPID_CLIENT_EXTERN void open(const Url& url, const ConnectionSettings& settings); + + /** + * Opens a connection to a broker. + * + * @param the settings to use (host, port etc). @see ConnectionSettings. + */ + QPID_CLIENT_EXTERN void open(const ConnectionSettings& settings); + + /** + * Close the connection. + * + * Any further use of this connection (without reopening it) will + * not succeed. + */ + QPID_CLIENT_EXTERN void close(); + + /** + * Create a new session on this connection. Sessions allow + * multiple streams of work to be multiplexed over the same + * connection. The returned Session provides functions to send + * commands to the broker. + * + * Session functions are synchronous. In other words, a Session + * function will send a command to the broker and does not return + * until it receives the broker's response confirming the command + * was executed. + * + * AsyncSession provides asynchronous versions of the same + * functions. These functions send a command to the broker but do + * not wait for a response. + * + * You can convert a Session s into an AsyncSession as follows: + * @code + * #include <qpid/client/AsyncSession.h> + * AsyncSession as = async(s); + * @endcode + * + * You can execute a single command asynchronously will a Session s + * like ths: + * @code + * async(s).messageTransfer(...); + * @endcode + * + * Using an AsyncSession is faster for sending large numbers of + * commands, since each command is sent as soon as possible + * without waiting for the previous command to be confirmed. + * + * However with AsyncSession you cannot assume that a command has + * completed until you explicitly synchronize. The simplest way to + * do this is to call Session::sync() or AsyncSession::sync(). + * Both of these functions wait for the broker to confirm all + * commands issued so far on the session. + * + *@param name: A name to identify the session. @see qpid::SessionId + * If the name is empty (the default) then a unique name will be + * chosen using a Universally-unique identifier (UUID) algorithm. + */ + QPID_CLIENT_EXTERN Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0); + + /** + * Resume a suspended session. A session may be resumed + * on a different connection to the one that created it. + */ + QPID_CLIENT_EXTERN void resume(Session& session); + + QPID_CLIENT_EXTERN bool isOpen() const; + + /** In a cluster, returns the initial set of known broker URLs + * at the time of connection. + */ + QPID_CLIENT_EXTERN std::vector<Url> getInitialBrokers(); + + QPID_CLIENT_EXTERN void registerFailureCallback ( boost::function<void ()> fn ); + + /** + * Return the set of client negotiated settings + */ + QPID_CLIENT_EXTERN const ConnectionSettings& getNegotiatedSettings(); + + friend struct ConnectionAccess; ///<@internal + friend class SessionBase_0_10; ///<@internal +}; + +}} // namespace qpid::client + + +#endif /*!QPID_CLIENT_CONNECTION_H*/ diff --git a/qpid/cpp/include/qpid/client/ConnectionSettings.h b/qpid/cpp/include/qpid/client/ConnectionSettings.h new file mode 100644 index 0000000000..2b6b86f891 --- /dev/null +++ b/qpid/cpp/include/qpid/client/ConnectionSettings.h @@ -0,0 +1,134 @@ +#ifndef QPID_CLIENT_CONNECTIONSETTINGS_H +#define QPID_CLIENT_CONNECTIONSETTINGS_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/client/ClientImportExport.h" +#include "qpid/sys/IntegerTypes.h" +#include <string> + +namespace qpid { + +namespace sys { +class Socket; +} + +namespace client { + +/** + * Settings for a Connection. + */ +struct QPID_CLIENT_CLASS_EXTERN ConnectionSettings { + + QPID_CLIENT_EXTERN ConnectionSettings(); + QPID_CLIENT_EXTERN virtual ~ConnectionSettings(); + + /** + * Allows socket to be configured; default only sets tcp-nodelay + * based on the flag set. Can be overridden. + */ + QPID_CLIENT_EXTERN virtual void configureSocket(qpid::sys::Socket&) const; + + /** + * The protocol used for the connection (defaults to 'tcp') + */ + std::string protocol; + + /** + * The host (or ip address) to connect to (defaults to 'localhost'). + */ + std::string host; + /** + * The port to connect to (defaults to 5672). + */ + uint16_t port; + /** + * Allows an AMQP 'virtual host' to be specified for the + * connection. + */ + std::string virtualhost; + + /** + * The username to use when authenticating the connection. If not + * specified the current users login is used if available. + */ + std::string username; + /** + * The password to use when authenticating the connection. + */ + std::string password; + /** + * The SASL mechanism to use when authenticating the connection; + * the options are currently PLAIN or ANONYMOUS. + */ + std::string mechanism; + /** + * Allows a locale to be specified for the connection. + */ + std::string locale; + /** + * Allows a heartbeat frequency to be specified + */ + uint16_t heartbeat; + /** + * The maximum number of channels that the client will request for + * use on this connection. + */ + uint16_t maxChannels; + /** + * The maximum frame size that the client will request for this + * connection. + */ + uint16_t maxFrameSize; + /** + * Limit the size of the connections send buffer . The buffer + * is limited to bounds * maxFrameSize. + */ + unsigned int bounds; + /** + * If true, TCP_NODELAY will be set for the connection. + */ + bool tcpNoDelay; + /** + * SASL service name + */ + std::string service; + /** + * Minimum acceptable strength of any SASL negotiated security + * layer. 0 means no security layer required. + */ + unsigned int minSsf; + /** + * Maximum acceptable strength of any SASL negotiated security + * layer. 0 means no security layer allowed. + */ + unsigned int maxSsf; + /** + * SSL cert-name for the connection. Overrides global SSL + * settings. Used only when a client connects to the broker. + */ + std::string sslCertName; +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_CONNECTIONSETTINGS_H*/ diff --git a/qpid/cpp/include/qpid/client/FailoverListener.h b/qpid/cpp/include/qpid/client/FailoverListener.h new file mode 100644 index 0000000000..53c7c26211 --- /dev/null +++ b/qpid/cpp/include/qpid/client/FailoverListener.h @@ -0,0 +1,88 @@ +#ifndef QPID_CLIENT_FAILOVERLISTENER_H +#define QPID_CLIENT_FAILOVERLISTENER_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/client/ClientImportExport.h" +#include "qpid/client/MessageListener.h" +#include "qpid/client/Connection.h" +#include "qpid/client/Session.h" +#include "qpid/client/SubscriptionManager.h" +#include "qpid/Url.h" +#include "qpid/sys/Mutex.h" +#include "qpid/sys/Runnable.h" +#include "qpid/sys/Thread.h" +#include <vector> + +namespace qpid { +namespace client { + + +/** + * Listen for updates from the amq.failover exchange. + * + * In a cluster, the amq.failover exchange provides updates whenever + * the cluster membership changes. This class subscribes to the + * failover exchange and providees the latest list of known brokers. + * + * You can also subscribe to amq.failover yourself and use + * FailoverListener::decode to extract a list of broker URLs from a + * failover exchange message. + */ +class QPID_CLIENT_CLASS_EXTERN FailoverListener : private MessageListener, private qpid::sys::Runnable +{ + public: + /** The name of the standard failover exchange amq.failover */ + static QPID_CLIENT_EXTERN const std::string AMQ_FAILOVER; + + /** Extract the broker list from a failover exchange message */ + static QPID_CLIENT_EXTERN std::vector<Url> getKnownBrokers(const Message& m); + + /** Subscribe to amq.failover exchange. */ + QPID_CLIENT_EXTERN FailoverListener(Connection); + + /** Subscribe to amq.failover exchange. + *@param useInitial If true use the connection's initial brokers as + * the initial value of getKnownBrokers + */ + QPID_CLIENT_EXTERN FailoverListener(Connection, bool useInitial); + + QPID_CLIENT_EXTERN ~FailoverListener(); + + /** Returns the latest list of known broker URLs. */ + QPID_CLIENT_EXTERN std::vector<Url> getKnownBrokers() const; + + private: + void received(Message& msg); + void run(); + void init(bool); + + mutable sys::Mutex lock; + Connection connection; + Session session; + SubscriptionManager subscriptions; + sys::Thread thread; + std::vector<Url> knownBrokers; +}; +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_FAILOVERLISTENER_H*/ diff --git a/qpid/cpp/include/qpid/client/FailoverManager.h b/qpid/cpp/include/qpid/client/FailoverManager.h new file mode 100644 index 0000000000..d3a0dbc976 --- /dev/null +++ b/qpid/cpp/include/qpid/client/FailoverManager.h @@ -0,0 +1,137 @@ +#ifndef QPID_CLIENT_FAILOVERMANAGER_H +#define QPID_CLIENT_FAILOVERMANAGER_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" +#include "qpid/client/AsyncSession.h" +#include "qpid/client/ClientImportExport.h" +#include "qpid/client/Connection.h" +#include "qpid/client/ConnectionSettings.h" +#include "qpid/client/FailoverListener.h" +#include "qpid/sys/Monitor.h" +#include <vector> + +namespace qpid { +namespace client { + +struct CannotConnectException : qpid::Exception +{ + CannotConnectException(const std::string& m) : qpid::Exception(m) {} +}; + +/** + * Utility to manage failover. + */ +class QPID_CLIENT_CLASS_EXTERN FailoverManager +{ + public: + /** + * Interface to implement for doing work that can be resumed on + * failover + */ + struct Command + { + /** + * This method will be called with isRetry=false when the + * command is first executed. The session to use for the work + * will be passed to the implementing class. If the connection + * fails while the execute call is in progress, the + * FailoverManager controlling the execution will re-establish + * a connection, open a new session and call back to the + * Command implementations execute method with the new session + * and isRetry=true. + */ + virtual void execute(AsyncSession& session, bool isRetry) = 0; + virtual ~Command() {} + }; + + struct ReconnectionStrategy + { + /** + * This method is called by the FailoverManager prior to + * establishing a connection (or re-connection) and can be + * used if the application wishes to edit or re-order the list + * which will default to the list of known brokers for the + * last connection. + */ + virtual void editUrlList(std::vector<Url>& urls) = 0; + virtual ~ReconnectionStrategy() {} + }; + + /** + * Create a manager to control failover for a logical connection. + * + * @param settings the initial connection settings + * @param strategy optional stratgey callback allowing application + * to edit or reorder the list of urls to which reconnection is + * attempted + */ + QPID_CLIENT_EXTERN FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0); + /** + * Return the current connection if open or attept to reconnect to + * the specified list of urls. If no list is specified the list of + * known brokers from the last connection will be used. If no list + * is specified and this is the first connect attempt, the host + * and port from the initial settings will be used. + * + * If the full list is tried and all attempts fail, + * CannotConnectException is thrown. + */ + QPID_CLIENT_EXTERN Connection& connect(std::vector<Url> brokers = std::vector<Url>()); + /** + * Return the current connection whether open or not + */ + QPID_CLIENT_EXTERN Connection& getConnection(); + /** + * Close the current connection + */ + QPID_CLIENT_EXTERN void close(); + /** + * Reliably execute the specified command. This involves creating + * a session on which to carry out the work of the command, + * handling failover occuring while exeuting that command and + * re-starting the work. + * + * Multiple concurrent threads can call execute with different + * commands; each thread will be allocated its own + * session. FailoverManager will coordinate the different threads + * on failover to ensure they continue to use the same logical + * connection. + */ + QPID_CLIENT_EXTERN void execute(Command&); + private: + enum State {IDLE, CONNECTING, CANT_CONNECT}; + + qpid::sys::Monitor lock; + Connection connection; + std::auto_ptr<FailoverListener> failoverListener; + ConnectionSettings settings; + ReconnectionStrategy* strategy; + State state; + + void attempt(Connection&, ConnectionSettings settings, std::vector<Url> urls); + void attempt(Connection&, ConnectionSettings settings); +}; +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_FAILOVERMANAGER_H*/ diff --git a/qpid/cpp/include/qpid/client/FlowControl.h b/qpid/cpp/include/qpid/client/FlowControl.h new file mode 100644 index 0000000000..bff7071b3b --- /dev/null +++ b/qpid/cpp/include/qpid/client/FlowControl.h @@ -0,0 +1,75 @@ +#ifndef QPID_CLIENT_FLOWCONTROL_H +#define QPID_CLIENT_FLOWCONTROL_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/IntegerTypes.h> + +namespace qpid { +namespace client { + +/** + * Flow control works by associating a finite amount of "credit" + * with a subscription. + * + * Credit includes a message count and a byte count. Each message + * received decreases the message count by one, and the byte count by + * the size of the message. Either count can have the special value + * UNLIMITED which is never decreased. + * + * A subscription's credit is exhausted when the message count is 0 or + * the byte count is too small for the next available message. The + * subscription will not receive any further messages until is credit + * is renewed. + * + * In "window mode" credit is automatically renewed when a message is + * completed (which by default happens when it is accepted). In + * non-window mode credit is not automatically renewed, it must be + * explicitly re-set (@see Subscription) + */ +struct FlowControl { + static const uint32_t UNLIMITED=0xFFFFFFFF; + FlowControl(uint32_t messages_=0, uint32_t bytes_=0, bool window_=false) + : messages(messages_), bytes(bytes_), window(window_) {} + + static FlowControl messageCredit(uint32_t messages_) { return FlowControl(messages_,UNLIMITED,false); } + static FlowControl messageWindow(uint32_t messages_) { return FlowControl(messages_,UNLIMITED,true); } + static FlowControl byteCredit(uint32_t bytes_) { return FlowControl(UNLIMITED,bytes_,false); } + static FlowControl byteWindow(uint32_t bytes_) { return FlowControl(UNLIMITED,bytes_,true); } + static FlowControl unlimited() { return FlowControl(UNLIMITED, UNLIMITED, false); } + static FlowControl zero() { return FlowControl(0, 0, false); } + + /** Message credit: subscription can accept up to this many messages. */ + uint32_t messages; + /** Byte credit: subscription can accept up to this many bytes of message content. */ + uint32_t bytes; + /** Window mode. If true credit is automatically renewed as messages are acknowledged. */ + bool window; + + bool operator==(const FlowControl& x) { + return messages == x.messages && bytes == x.bytes && window == x.window; + }; +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_FLOWCONTROL_H*/ diff --git a/qpid/cpp/include/qpid/client/Future.h b/qpid/cpp/include/qpid/client/Future.h new file mode 100644 index 0000000000..630a7e03c0 --- /dev/null +++ b/qpid/cpp/include/qpid/client/Future.h @@ -0,0 +1,59 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _Future_ +#define _Future_ + +#include <boost/bind.hpp> +#include <boost/shared_ptr.hpp> +#include "qpid/Exception.h" +#include "qpid/framing/SequenceNumber.h" +#include "qpid/client/FutureCompletion.h" +#include "qpid/client/FutureResult.h" +#include "qpid/client/ClientImportExport.h" + +namespace qpid { +namespace client { + +/**@internal */ +class QPID_CLIENT_CLASS_EXTERN Future +{ + framing::SequenceNumber command; + boost::shared_ptr<FutureResult> result; + bool complete; + +public: + Future() : complete(false) {} + Future(const framing::SequenceNumber& id) : command(id), complete(false) {} + + std::string getResult(SessionImpl& session) { + if (result) return result->getResult(session); + else throw Exception("Result not expected"); + } + + QPID_CLIENT_EXTERN void wait(SessionImpl& session); + QPID_CLIENT_EXTERN bool isComplete(SessionImpl& session); + QPID_CLIENT_EXTERN void setFutureResult(boost::shared_ptr<FutureResult> r); +}; + +}} + +#endif diff --git a/qpid/cpp/include/qpid/client/FutureCompletion.h b/qpid/cpp/include/qpid/client/FutureCompletion.h new file mode 100644 index 0000000000..0970f494b7 --- /dev/null +++ b/qpid/cpp/include/qpid/client/FutureCompletion.h @@ -0,0 +1,49 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _FutureCompletion_ +#define _FutureCompletion_ + +#include "qpid/framing/amqp_framing.h" +#include "qpid/sys/Monitor.h" + +namespace qpid { +namespace client { + +///@internal +class FutureCompletion +{ +protected: + mutable sys::Monitor lock; + bool complete; + +public: + FutureCompletion(); + virtual ~FutureCompletion(){} + bool isComplete() const; + void waitForCompletion() const; + void completed(); +}; + +}} + + +#endif diff --git a/qpid/cpp/include/qpid/client/FutureResult.h b/qpid/cpp/include/qpid/client/FutureResult.h new file mode 100644 index 0000000000..ead4929571 --- /dev/null +++ b/qpid/cpp/include/qpid/client/FutureResult.h @@ -0,0 +1,49 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _FutureResult_ +#define _FutureResult_ + +#include <string> + +#include "qpid/client/ClientImportExport.h" +#include "qpid/framing/amqp_framing.h" +#include "qpid/client/FutureCompletion.h" + +namespace qpid { +namespace client { + +class SessionImpl; + +///@internal +class QPID_CLIENT_CLASS_EXTERN FutureResult : public FutureCompletion +{ + std::string result; +public: + QPID_CLIENT_EXTERN const std::string& getResult(SessionImpl& session) const; + void received(const std::string& result); +}; + +}} + + + +#endif diff --git a/qpid/cpp/include/qpid/client/Handle.h b/qpid/cpp/include/qpid/client/Handle.h new file mode 100644 index 0000000000..b8315481a9 --- /dev/null +++ b/qpid/cpp/include/qpid/client/Handle.h @@ -0,0 +1,71 @@ +#ifndef QPID_CLIENT_HANDLE_H +#define QPID_CLIENT_HANDLE_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/client/ClientImportExport.h" + +namespace qpid { +namespace client { + +template <class> class PrivateImplRef; + +/** + * A handle is like a pointer: refers to an underlying implementation object. + * Copying the handle does not copy the object. + * + * Handles can be null, like a 0 pointer. Use isValid(), isNull() or the + * conversion to bool to test for a null handle. + */ +template <class T> class Handle { + public: + + /**@return true if handle is valid, i.e. not null. */ + QPID_CLIENT_INLINE_EXTERN bool isValid() const { return impl; } + + /**@return true if handle is null. It is an error to call any function on a null handle. */ + QPID_CLIENT_INLINE_EXTERN bool isNull() const { return !impl; } + + /** Conversion to bool supports idiom if (handle) { handle->... } */ + QPID_CLIENT_INLINE_EXTERN operator bool() const { return impl; } + + /** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */ + QPID_CLIENT_INLINE_EXTERN bool operator !() const { return !impl; } + + void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; } + + protected: + typedef T Impl; + QPID_CLIENT_INLINE_EXTERN Handle() :impl() {} + + // Not implemented,subclasses must implement. + QPID_CLIENT_EXTERN Handle(const Handle&); + QPID_CLIENT_EXTERN Handle& operator=(const Handle&); + + Impl* impl; + + friend class PrivateImplRef<T>; // FIXME aconway 2009-04-30: Specify +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_HANDLE_H*/ diff --git a/qpid/cpp/include/qpid/client/LocalQueue.h b/qpid/cpp/include/qpid/client/LocalQueue.h new file mode 100644 index 0000000000..1a19a8499d --- /dev/null +++ b/qpid/cpp/include/qpid/client/LocalQueue.h @@ -0,0 +1,120 @@ +#ifndef QPID_CLIENT_LOCALQUEUE_H +#define QPID_CLIENT_LOCALQUEUE_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/client/ClientImportExport.h" +#include "qpid/client/Handle.h" +#include "qpid/client/Message.h" +#include "qpid/sys/Time.h" + +namespace qpid { +namespace client { + +class LocalQueueImpl; +template <class T> class PrivateImplRef; + +/** + * A local queue to collect messages retrieved from a remote broker + * queue. Create a queue and subscribe it using the SubscriptionManager. + * Messages from the remote queue on the broker will be stored in the + * local queue until you retrieve them. + * + * \ingroup clientapi + * + * \details Using a Local Queue + * + * <pre> + * LocalQueue local_queue; + * subscriptions.subscribe(local_queue, string("message_queue")); + * for (int i=0; i<10; i++) { + * Message message = local_queue.get(); + * std::cout << message.getData() << std::endl; + * } + * </pre> + * + * <h2>Getting Messages</h2> + * + * <ul><li> + * <p>get()</p> + * <pre>Message message = local_queue.get();</pre> + * <pre>// Specifying timeouts (TIME_SEC, TIME_MSEC, TIME_USEC, TIME_NSEC) + *#include <qpid/sys/Time.h> + *Message message; + *local_queue.get(message, 5*sys::TIME_SEC);</pre></li></ul> + * + * <h2>Checking size</h2> + * <ul><li> + * <p>empty()</p> + * <pre>if (local_queue.empty()) { ... }</pre></li> + * <li><p>size()</p> + * <pre>std::cout << local_queue.size();</pre></li> + * </ul> + */ + +class QPID_CLIENT_CLASS_EXTERN LocalQueue : public Handle<LocalQueueImpl> { + public: + /** Create a local queue. Subscribe the local queue to a remote broker + * queue with a SubscriptionManager. + * + * LocalQueue is an alternative to implementing a MessageListener. + */ + QPID_CLIENT_EXTERN LocalQueue(); + QPID_CLIENT_EXTERN LocalQueue(const LocalQueue&); + QPID_CLIENT_EXTERN ~LocalQueue(); + QPID_CLIENT_EXTERN LocalQueue& operator=(const LocalQueue&); + + /** Wait up to timeout for the next message from the local queue. + *@param result Set to the message from the queue. + *@param timeout wait up this timeout for a message to appear. + *@return true if result was set, false if queue was empty after timeout. + */ + QPID_CLIENT_EXTERN bool get(Message& result, sys::Duration timeout=0); + + /** Get the next message off the local queue, or wait up to the timeout + * for message from the broker queue. + *@param timeout wait up this timeout for a message to appear. + *@return message from the queue. + *@throw ClosedException if subscription is closed or timeout exceeded. + */ + QPID_CLIENT_EXTERN Message get(sys::Duration timeout=sys::TIME_INFINITE); + + /** Synonym for get() */ + QPID_CLIENT_EXTERN Message pop(sys::Duration timeout=sys::TIME_INFINITE); + + /** Return true if local queue is empty. */ + QPID_CLIENT_EXTERN bool empty() const; + + /** Number of messages on the local queue */ + QPID_CLIENT_EXTERN size_t size() const; + + LocalQueue(LocalQueueImpl*); ///<@internal + + + private: + typedef LocalQueueImpl Impl; + friend class PrivateImplRef<LocalQueue>; +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_LOCALQUEUE_H*/ diff --git a/qpid/cpp/include/qpid/client/Message.h b/qpid/cpp/include/qpid/client/Message.h new file mode 100644 index 0000000000..ba50dda9ba --- /dev/null +++ b/qpid/cpp/include/qpid/client/Message.h @@ -0,0 +1,175 @@ +#ifndef QPID_CLIENT_MESSAGE_H +#define QPID_CLIENT_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/client/ClientImportExport.h" +#include "qpid/framing/MessageProperties.h" +#include "qpid/framing/DeliveryProperties.h" +#include <string> + +namespace qpid { + +namespace framing { +class FieldTable; +class SequenceNumber; // FIXME aconway 2009-04-17: remove with getID? +} + +namespace client { + +class MessageImpl; + +/** + * A message sent to or received from the broker. + * + * \ingroup clientapi + * \details + * + * <h2>Getting and setting message contents</h2> + * + * <ul> + * <li> + * <p>getData()</p> + * <pre>std::cout << "Response: " << message.getData() << std::endl;</pre> + * </li> + * <li> + * <p>setData()</p> + * <pre>message.setData("That's all, folks!");</pre></li> + * <li> + * <p>appendData()</p> + * <pre>message.appendData(" ... let's add a bit more ...");</pre></li> + * </ul> + * + * <h2>Getting and Setting Delivery Properties</h2> + * + * <ul> + * <li> + * <p>getDeliveryProperties()</p> + * <pre>message.getDeliveryProperties().setRoutingKey("control");</pre> + * <pre>message.getDeliveryProperties().setDeliveryMode(PERSISTENT);</pre> + * <pre>message.getDeliveryProperties().setPriority(9);</pre> + * <pre>message.getDeliveryProperties().setTtl(100);</pre></li> + * + * <li> + * <p>hasDeliveryProperties()</p> + * <pre>if (! message.hasDeliveryProperties()) { + * ... + *}</pre></li> + * </ul> + * + * <h2>Getting and Setting Message Properties</h2> + * + * <ul> + * <li> + * <p>getMessageProperties()</p> + * <pre> + *request.getMessageProperties().setReplyTo(ReplyTo("amq.direct", response_queue.str())); + * </pre> + * <pre> + *routingKey = request.getMessageProperties().getReplyTo().getRoutingKey(); + *exchange = request.getMessageProperties().getReplyTo().getExchange(); + * </pre> + * <pre>message.getMessageProperties().setContentType("text/plain");</pre> + * <pre>message.getMessageProperties().setContentEncoding("text/plain");</pre> + * </li> + * <li> + * <p>hasMessageProperties()</p> + * <pre>request.getMessageProperties().hasReplyTo();</pre> + * </li> + * </ul> + * + * <h2>Getting and Setting Application Headers</h2> + * + * <ul> + * <li> + * <p>getHeaders()</p> + * <pre> + *message.getHeaders().getString("control"); + * </pre> + * <pre> + *message.getHeaders().setString("control","continue"); + * </pre></li> + * </ul> + * + * + */ +class QPID_CLIENT_CLASS_EXTERN Message +{ +public: + /** Create a Message. + *@param data Data for the message body. + *@param routingKey Passed to the exchange that routes the message. + */ + QPID_CLIENT_EXTERN Message( + const std::string& data=std::string(), + const std::string& routingKey=std::string()); + Message(MessageImpl*); ///< @internal + QPID_CLIENT_EXTERN Message(const Message&); + QPID_CLIENT_EXTERN ~Message(); + QPID_CLIENT_EXTERN Message& operator=(const Message&); + QPID_CLIENT_EXTERN void swap(Message&); + + QPID_CLIENT_EXTERN void setData(const std::string&); + QPID_CLIENT_EXTERN const std::string& getData() const; + QPID_CLIENT_EXTERN std::string& getData(); + + QPID_CLIENT_EXTERN void appendData(const std::string&); + + QPID_CLIENT_EXTERN bool hasMessageProperties() const; + QPID_CLIENT_EXTERN framing::MessageProperties& getMessageProperties(); + QPID_CLIENT_EXTERN const framing::MessageProperties& getMessageProperties() const; + + QPID_CLIENT_EXTERN bool hasDeliveryProperties() const; + QPID_CLIENT_EXTERN framing::DeliveryProperties& getDeliveryProperties(); + QPID_CLIENT_EXTERN const framing::DeliveryProperties& getDeliveryProperties() const; + + + /** The destination of messages sent to the broker is the exchange + * name. The destination of messages received from the broker is + * the delivery tag identifyig the local subscription (often this + * is the name of the subscribed queue.) + */ + QPID_CLIENT_EXTERN std::string getDestination() const; + + /** Check the redelivered flag. */ + QPID_CLIENT_EXTERN bool isRedelivered() const; + /** Set the redelivered flag. */ + QPID_CLIENT_EXTERN void setRedelivered(bool redelivered); + + /** Get a modifyable reference to the message headers. */ + QPID_CLIENT_EXTERN framing::FieldTable& getHeaders(); + + /** Get a non-modifyable reference to the message headers. */ + QPID_CLIENT_EXTERN const framing::FieldTable& getHeaders() const; + + // FIXME aconway 2009-04-17: does this need to be in public API? + ///@internal + QPID_CLIENT_EXTERN const framing::SequenceNumber& getId() const; + + private: + MessageImpl* impl; + friend class MessageImpl; // Helper template for implementation +}; + +}} + +#endif /*!QPID_CLIENT_MESSAGE_H*/ diff --git a/qpid/cpp/include/qpid/client/MessageListener.h b/qpid/cpp/include/qpid/client/MessageListener.h new file mode 100644 index 0000000000..3ca2fa964a --- /dev/null +++ b/qpid/cpp/include/qpid/client/MessageListener.h @@ -0,0 +1,101 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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/client/ClientImportExport.h" + +#ifndef _MessageListener_ +#define _MessageListener_ + +#include "qpid/client/Message.h" + +namespace qpid { +namespace client { + + /** + * Implement a subclass of MessageListener and subscribe it using + * the SubscriptionManager to receive messages. + * + * Another way to receive messages is by using a LocalQueue. + * + * \ingroup clientapi + * \details + * + * <h2>Using a MessageListener</h2> + * + * <ul> + * <li> + * <p>The received() function is called when a message arrives:</p> + * <pre>virtual void received(Message& message)=0;</pre> + * </li> + * <li> + * <p>Derive your own listener, implement the received() function:</p> + * <pre> + * class Listener : public MessageListener { + * private: + * SubscriptionManager& subscriptions; + * public: + * Listener(SubscriptionManager& subscriptions); + * virtual void received(Message& message); + * }; + * + * Listener::Listener(SubscriptionManager& subs) : subscriptions(subs) + * {} + * + * void Listener::received(Message& message) { + * std::cout << "Message: " << message.getData() << std::endl; + * if (message.getData() == "That's all, folks!") { + * std::cout << "Shutting down listener for " << message.getDestination() + * << std::endl; + * subscriptions.cancel(message.getDestination()); + * } + * } + *</pre> + * <pre> + * SubscriptionManager subscriptions(session); + * + * // Create a listener and subscribe it to the queue named "message_queue" + * Listener listener(subscriptions); + * subscriptions.subscribe(listener, "message_queue"); + * + * // Receive messages until the subscription is cancelled + * // by Listener::received() + * subscriptions.run(); + * </pre> + * </li> + * </ul> + * + */ + + class QPID_CLIENT_CLASS_EXTERN MessageListener{ + public: + QPID_CLIENT_EXTERN virtual ~MessageListener(); + + /** Called for each message arriving from the broker. Override + * in your own subclass to process messages. + */ + virtual void received(Message& msg) = 0; + }; + +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/client/MessageReplayTracker.h b/qpid/cpp/include/qpid/client/MessageReplayTracker.h new file mode 100644 index 0000000000..06a3f29c7d --- /dev/null +++ b/qpid/cpp/include/qpid/client/MessageReplayTracker.h @@ -0,0 +1,73 @@ +#ifndef QPID_CLIENT_MESSAGEREPLAYTRACKER_H +#define QPID_CLIENT_MESSAGEREPLAYTRACKER_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/client/AsyncSession.h" +#include "qpid/client/Message.h" +#include "qpid/client/ClientImportExport.h" +#include <list> +#include <string> + +namespace qpid { +namespace client { + +/** + * Utility to track messages sent asynchronously, allowing those that + * are indoubt to be replayed over a new session. + */ +class QPID_CLIENT_CLASS_EXTERN MessageReplayTracker +{ + public: + QPID_CLIENT_EXTERN MessageReplayTracker(uint flushInterval); + QPID_CLIENT_EXTERN void send(const Message& message, const std::string& destination = ""); + QPID_CLIENT_EXTERN void init(AsyncSession session); + QPID_CLIENT_EXTERN void replay(AsyncSession session); + QPID_CLIENT_EXTERN void setFlushInterval(uint interval); + QPID_CLIENT_EXTERN uint getFlushInterval(); + QPID_CLIENT_EXTERN void checkCompletion(); + + template <class F> void foreach(F& f) { + for (std::list<ReplayRecord>::const_iterator i = buffer.begin(); i != buffer.end(); i++) { + f(i->message); + } + } + + private: + struct ReplayRecord + { + Completion status; + Message message; + std::string destination; + + ReplayRecord(const Message& message, const std::string& destination); + void send(MessageReplayTracker&); + bool isComplete(); + }; + + AsyncSession session; + uint flushInterval; + uint count; + std::list<ReplayRecord> buffer; +}; +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_MESSAGEREPLAYTRACKER_H*/ diff --git a/qpid/cpp/include/qpid/client/QueueOptions.h b/qpid/cpp/include/qpid/client/QueueOptions.h new file mode 100644 index 0000000000..3984b63fdd --- /dev/null +++ b/qpid/cpp/include/qpid/client/QueueOptions.h @@ -0,0 +1,129 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "qpid/client/ClientImportExport.h" +#include "qpid/framing/FieldTable.h" + +#ifndef _QueueOptions_ +#define _QueueOptions_ + +namespace qpid { +namespace client { + +enum QueueSizePolicy {NONE, REJECT, FLOW_TO_DISK, RING, RING_STRICT}; +enum QueueOrderingPolicy {FIFO, LVQ, LVQ_NO_BROWSE}; + +/** + * A help class to set options on the Queue. Create a configured args while + * still allowing any custom configuration via the FieldTable base class + */ +class QPID_CLIENT_CLASS_EXTERN QueueOptions: public framing::FieldTable +{ + public: + QPID_CLIENT_EXTERN QueueOptions(); + QPID_CLIENT_EXTERN virtual ~QueueOptions(); + + /** + * Sets the queue sizing policy + * + * @param sp SizePolicy + * REJECT - reject if queue greater than size/count + * FLOW_TO_DISK - page messages to disk from this point is greater than size/count + * RING - limit the queue to size/count and over-write old messages round a ring + * RING_STRICT - limit the queue to size/count and reject is head == tail + * NONE - Use default broker sizing policy + * @param maxSize Set the max number of bytes for the sizing policies + * @param setMaxCount Set the max number of messages for the sizing policies + */ + QPID_CLIENT_EXTERN void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount ); + + /** + * Enables the persisting of a queue to the store module when a cluster fails down to it's last + * node. Does so optimistically. Will start persisting when cluster count >1 again. + */ + QPID_CLIENT_EXTERN void setPersistLastNode(); + + /** + * Sets the odering policy on the Queue, default ordering is FIFO. + */ + QPID_CLIENT_EXTERN void setOrdering(QueueOrderingPolicy op); + + /** + * Use broker defualt sizing ploicy + */ + QPID_CLIENT_EXTERN void clearSizePolicy(); + + /** + * Clear Persist Last Node Policy + */ + QPID_CLIENT_EXTERN void clearPersistLastNode(); + + /** + * get the key used match LVQ in args for message transfer + */ + QPID_CLIENT_EXTERN void getLVQKey(std::string& key); + + /** + * Use default odering policy + */ + QPID_CLIENT_EXTERN void clearOrdering(); + + /** + * Turns on event generation for this queue (either enqueue only + * or for enqueue and dequeue events); the events can then be + * processed by a regsitered broker plugin. + * + * DEPRECATED + * + * This is confusing to anyone who sees only the function call + * and not the variable name / doxygen. Consider the following call: + * + * options.enableQueueEvents(false); + * + * It looks like it disables queue events, but what it really does is + * enable both enqueue and dequeue events. + * + * Use setInt() instead: + * + * options.setInt("qpid.queue_event_generation", 2); + */ + + QPID_CLIENT_EXTERN void enableQueueEvents(bool enqueueOnly); + + static QPID_CLIENT_EXTERN const std::string strMaxCountKey; + static QPID_CLIENT_EXTERN const std::string strMaxSizeKey; + static QPID_CLIENT_EXTERN const std::string strTypeKey; + static QPID_CLIENT_EXTERN const std::string strREJECT; + static QPID_CLIENT_EXTERN const std::string strFLOW_TO_DISK; + static QPID_CLIENT_EXTERN const std::string strRING; + static QPID_CLIENT_EXTERN const std::string strRING_STRICT; + static QPID_CLIENT_EXTERN const std::string strLastValueQueue; + static QPID_CLIENT_EXTERN const std::string strPersistLastNode; + static QPID_CLIENT_EXTERN const std::string strLVQMatchProperty; + static QPID_CLIENT_EXTERN const std::string strLastValueQueueNoBrowse; + static QPID_CLIENT_EXTERN const std::string strQueueEventMode; +}; + +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/client/Session.h b/qpid/cpp/include/qpid/client/Session.h new file mode 100644 index 0000000000..c40549bbc5 --- /dev/null +++ b/qpid/cpp/include/qpid/client/Session.h @@ -0,0 +1,39 @@ +#ifndef QPID_CLIENT_SESSION_H +#define QPID_CLIENT_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/client/Session_0_10.h" + +namespace qpid { +namespace client { + +/** + * Session is an alias for Session_0_10 + * + * \ingroup clientapi + */ +typedef Session_0_10 Session; + + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_SESSION_H*/ diff --git a/qpid/cpp/include/qpid/client/SessionBase_0_10.h b/qpid/cpp/include/qpid/client/SessionBase_0_10.h new file mode 100644 index 0000000000..ea50ab32f7 --- /dev/null +++ b/qpid/cpp/include/qpid/client/SessionBase_0_10.h @@ -0,0 +1,110 @@ +#ifndef QPID_CLIENT_SESSIONBASE_H +#define QPID_CLIENT_SESSIONBASE_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/SessionId.h" +#include "qpid/framing/amqp_structs.h" +#include "qpid/client/Message.h" +#include "qpid/client/Completion.h" +#include "qpid/client/TypedResult.h" +#include "qpid/client/ClientImportExport.h" +#include <string> + +namespace qpid { +namespace client { + +class Connection; +class SessionImpl; + +using std::string; +using framing::Content; +using framing::FieldTable; +using framing::SequenceNumber; +using framing::SequenceSet; +using framing::SequenceNumberSet; +using qpid::SessionId; +using framing::Xid; + +/** Unit of message credit: messages or bytes */ +enum CreditUnit { MESSAGE_CREDIT=0, BYTE_CREDIT=1, UNLIMITED_CREDIT=0xFFFFFFFF }; + +/** + * Base class for handles to an AMQP session. + * + * Subclasses provide the AMQP commands for a given + * version of the protocol. + */ +class QPID_CLIENT_CLASS_EXTERN SessionBase_0_10 { + public: + + ///@internal + QPID_CLIENT_EXTERN SessionBase_0_10(); + QPID_CLIENT_EXTERN ~SessionBase_0_10(); + + /** Get the session ID */ + QPID_CLIENT_EXTERN SessionId getId() const; + + /** Close the session. + * A session is automatically closed when all handles to it are destroyed. + */ + QPID_CLIENT_EXTERN void close(); + + /** + * Synchronize the session: sync() waits until all commands issued + * on this session so far have been completed by the broker. + * + * Note sync() is always synchronous, even on an AsyncSession object + * because that's almost always what you want. You can call + * AsyncSession::executionSync() directly in the unusual event + * that you want to do an asynchronous sync. + */ + QPID_CLIENT_EXTERN void sync(); + + /** Set the timeout for this session. */ + QPID_CLIENT_EXTERN uint32_t timeout(uint32_t seconds); + + /** Suspend the session - detach it from its connection */ + QPID_CLIENT_EXTERN void suspend(); + + /** Resume a suspended session with a new connection */ + QPID_CLIENT_EXTERN void resume(Connection); + + /** Get the channel associated with this session */ + QPID_CLIENT_EXTERN uint16_t getChannel() const; + + QPID_CLIENT_EXTERN void flush(); + QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceSet& ids, bool notifyPeer); + QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer); + QPID_CLIENT_EXTERN void sendCompletion(); + + QPID_CLIENT_EXTERN bool isValid() const; + + QPID_CLIENT_EXTERN Connection getConnection(); + protected: + boost::shared_ptr<SessionImpl> impl; + friend class SessionBase_0_10Access; +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_SESSIONBASE_H*/ diff --git a/qpid/cpp/include/qpid/client/Subscription.h b/qpid/cpp/include/qpid/client/Subscription.h new file mode 100644 index 0000000000..bb9b98e8ff --- /dev/null +++ b/qpid/cpp/include/qpid/client/Subscription.h @@ -0,0 +1,123 @@ +#ifndef QPID_CLIENT_SUBSCRIPTION_H +#define QPID_CLIENT_SUBSCRIPTION_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/client/Handle.h" +#include "qpid/client/Session.h" +#include "qpid/client/SubscriptionSettings.h" +#include "qpid/client/Message.h" +#include "qpid/client/ClientImportExport.h" + +namespace qpid { +namespace client { + +template <class> class PrivateImplRef; +class SubscriptionImpl; +class SubscriptionManager; + +/** + * A handle to an active subscription. Provides methods to query the subscription status + * and control acknowledgement (acquire and accept) of messages. + */ +class QPID_CLIENT_CLASS_EXTERN Subscription : public Handle<SubscriptionImpl> { + public: + QPID_CLIENT_EXTERN Subscription(SubscriptionImpl* = 0); + QPID_CLIENT_EXTERN Subscription(const Subscription&); + QPID_CLIENT_EXTERN ~Subscription(); + QPID_CLIENT_EXTERN Subscription& operator=(const Subscription&); + + + /** The name of the subscription, used as the "destination" for messages from the broker. + * Usually the same as the queue name but can be set differently. + */ + QPID_CLIENT_EXTERN std::string getName() const; + + /** Name of the queue this subscription subscribes to */ + QPID_CLIENT_EXTERN std::string getQueue() const; + + /** Get the flow control and acknowledgement settings for this subscription */ + QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const; + + /** Set the flow control parameters */ + QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&); + + /** Automatically acknowledge (acquire and accept) batches of n messages. + * You can disable auto-acknowledgement by setting n=0, and use acquire() and accept() + * to manually acquire and accept messages. + */ + QPID_CLIENT_EXTERN void setAutoAck(unsigned int n); + + /** Get the set of ID's for messages received by this subscription but not yet acquired. + * This will always be empty if getSettings().acquireMode=ACQUIRE_MODE_PRE_ACQUIRED + */ + QPID_CLIENT_EXTERN SequenceSet getUnacquired() const; + + /** Get the set of ID's for messages received by this subscription but not yet accepted. */ + QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const; + + /** Acquire messageIds and remove them from the unacquired set. + * oAdd them to the unaccepted set if getSettings().acceptMode == ACCEPT_MODE_EXPLICIT. + */ + QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds); + + /** Accept messageIds and remove them from the unaccepted set. + *@pre messageIds is a subset of getUnaccepted() + */ + QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds); + + /** Release messageIds and remove them from the unaccepted set. + *@pre messageIds is a subset of getUnaccepted() + */ + QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds); + + /* Acquire a single message */ + QPID_CLIENT_INLINE_EXTERN void acquire(const Message& m) { acquire(SequenceSet(m.getId())); } + + /* Accept a single message */ + QPID_CLIENT_INLINE_EXTERN void accept(const Message& m) { accept(SequenceSet(m.getId())); } + + /* Release a single message */ + QPID_CLIENT_INLINE_EXTERN void release(const Message& m) { release(SequenceSet(m.getId())); } + + /** Get the session associated with this subscription */ + QPID_CLIENT_EXTERN Session getSession() const; + + /** Get the subscription manager associated with this subscription */ + QPID_CLIENT_EXTERN SubscriptionManager getSubscriptionManager(); + + /** Cancel the subscription. */ + QPID_CLIENT_EXTERN void cancel(); + + /** Grant the specified amount of message credit */ + QPID_CLIENT_EXTERN void grantMessageCredit(uint32_t); + + /** Grant the specified amount of byte credit */ + QPID_CLIENT_EXTERN void grantByteCredit(uint32_t); + + private: + friend class PrivateImplRef<Subscription>; + friend class SubscriptionManager; +}; +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_SUBSCRIPTION_H*/ diff --git a/qpid/cpp/include/qpid/client/SubscriptionManager.h b/qpid/cpp/include/qpid/client/SubscriptionManager.h new file mode 100644 index 0000000000..b69819a8ff --- /dev/null +++ b/qpid/cpp/include/qpid/client/SubscriptionManager.h @@ -0,0 +1,292 @@ +#ifndef QPID_CLIENT_SUBSCRIPTIONMANAGER_H +#define QPID_CLIENT_SUBSCRIPTIONMANAGER_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/client/Session.h" +#include "qpid/client/Subscription.h" +#include "qpid/sys/Runnable.h" +#include "qpid/sys/Thread.h" +#include "qpid/client/ClientImportExport.h" +#include "qpid/client/MessageListener.h" +#include "qpid/client/LocalQueue.h" +#include "qpid/client/Handle.h" +#include <string> + +namespace qpid { +namespace client { + +class SubscriptionManagerImpl; + +/** + * A class to help create and manage subscriptions. + * + * Set up your subscriptions, then call run() to have messages + * delivered. + * + * \ingroup clientapi + * + * \details + * + * <h2>Subscribing and canceling subscriptions</h2> + * + * <ul> + * <li> + * <p>subscribe()</p> + * <pre> SubscriptionManager subscriptions(session); + * Listener listener(subscriptions); + * subscriptions.subscribe(listener, myQueue);</pre> + * <pre> SubscriptionManager subscriptions(session); + * LocalQueue local_queue; + * subscriptions.subscribe(local_queue, string("message_queue"));</pre></li> + * <li> + * <p>cancel()</p> + * <pre>subscriptions.cancel();</pre></li> + * </ul> + * + * <h2>Waiting for messages (and returning)</h2> + * + * <ul> + * <li> + * <p>run()</p> + * <pre> // Give up control to receive messages + * subscriptions.run();</pre></li> + * <li> + * <p>stop()</p> + * <pre>.// Use this code in a listener to return from run() + * subscriptions.stop();</pre></li> + * <li> + * <p>setAutoStop()</p> + * <pre>.// Return from subscriptions.run() when last subscription is cancelled + *.subscriptions.setAutoStop(true); + *.subscriptons.run(); + * </pre></li> + * <li> + * <p>Ending a subscription in a listener</p> + * <pre> + * void Listener::received(Message& message) { + * + * if (message.getData() == "That's all, folks!") { + * subscriptions.cancel(message.getDestination()); + * } + * } + * </pre> + * </li> + * </ul> + * + */ +class QPID_CLIENT_CLASS_EXTERN SubscriptionManager : public sys::Runnable, public Handle<SubscriptionManagerImpl> +{ + public: + /** Create a new SubscriptionManager associated with a session */ + QPID_CLIENT_EXTERN SubscriptionManager(const Session& session); + QPID_CLIENT_EXTERN SubscriptionManager(const SubscriptionManager&); + QPID_CLIENT_EXTERN ~SubscriptionManager(); + QPID_CLIENT_EXTERN SubscriptionManager& operator=(const SubscriptionManager&); + + /** + * Subscribe a MessagesListener to receive messages from queue. + * + * Provide your own subclass of MessagesListener to process + * incoming messages. It will be called for each message received. + * + *@param listener Listener object to receive messages. + *@param queue Name of the queue to subscribe to. + *@param settings settings for the subscription. + *@param name unique destination name for the subscription, defaults to queue name. + */ + QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener, + const std::string& queue, + const SubscriptionSettings& settings, + const std::string& name=std::string()); + + /** + * Subscribe a LocalQueue to receive messages from queue. + * + * Incoming messages are stored in the queue for you to retrieve. + * + *@param queue Name of the queue to subscribe to. + *@param flow initial FlowControl for the subscription. + *@param name unique destination name for the subscription, defaults to queue name. + * If not specified, the queue name is used. + */ + QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue, + const std::string& queue, + const SubscriptionSettings& settings, + const std::string& name=std::string()); + + /** + * Subscribe a MessagesListener to receive messages from queue. + * + * Provide your own subclass of MessagesListener to process + * incoming messages. It will be called for each message received. + * + *@param listener Listener object to receive messages. + *@param queue Name of the queue to subscribe to. + *@param name unique destination name for the subscription, defaults to queue name. + * If not specified, the queue name is used. + */ + QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener, + const std::string& queue, + const std::string& name=std::string()); + + /** + * Subscribe a LocalQueue to receive messages from queue. + * + * Incoming messages are stored in the queue for you to retrieve. + * + *@param queue Name of the queue to subscribe to. + *@param name unique destination name for the subscription, defaults to queue name. + * If not specified, the queue name is used. + */ + QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue, + const std::string& queue, + const std::string& name=std::string()); + + + /** Get a single message from a queue. + * (Note: this currently uses a subscription per invocation and is + * thus relatively expensive. The subscription is cancelled as + * part of each call which can trigger auto-deletion). + *@param result is set to the message from the queue. + *@param timeout wait up this timeout for a message to appear. + *@return true if result was set, false if no message available after timeout. + */ + QPID_CLIENT_EXTERN bool get(Message& result, const std::string& queue, sys::Duration timeout=0); + + /** Get a single message from a queue. + * (Note: this currently uses a subscription per invocation and is + * thus relatively expensive. The subscription is cancelled as + * part of each call which can trigger auto-deletion). + *@param timeout wait up this timeout for a message to appear. + *@return message from the queue. + *@throw Exception if the timeout is exceeded. + */ + QPID_CLIENT_EXTERN Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE); + + /** Get a subscription by name. + *@throw Exception if not found. + */ + QPID_CLIENT_EXTERN Subscription getSubscription(const std::string& name) const; + + /** Cancel a subscription. See also: Subscription.cancel() */ + QPID_CLIENT_EXTERN void cancel(const std::string& name); + + /** Deliver messages in the current thread until stop() is called. + * Only one thread may be running in a SubscriptionManager at a time. + * @see run + */ + QPID_CLIENT_EXTERN void run(); + + /** Start a new thread to deliver messages. + * Only one thread may be running in a SubscriptionManager at a time. + * @see start + */ + QPID_CLIENT_EXTERN void start(); + + /** + * Wait for the thread started by a call to start() to complete. + */ + QPID_CLIENT_EXTERN void wait(); + + /** If set true, run() will stop when all subscriptions + * are cancelled. If false, run will only stop when stop() + * is called. True by default. + */ + QPID_CLIENT_EXTERN void setAutoStop(bool set=true); + + /** Stop delivery. Causes run() to return, or the thread started with start() to exit. */ + QPID_CLIENT_EXTERN void stop(); + + static const uint32_t UNLIMITED=0xFFFFFFFF; + + /** Set the flow control for a subscription. */ + QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, const FlowControl& flow); + + /** Set the flow control for a subscription. + *@param name: name of the subscription. + *@param messages: message credit. + *@param bytes: byte credit. + *@param window: if true use window-based flow control. + */ + QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true); + + /** Set the default settings for subscribe() calls that don't + * include a SubscriptionSettings parameter. + */ + QPID_CLIENT_EXTERN void setDefaultSettings(const SubscriptionSettings& s); + + /** Get the default settings for subscribe() calls that don't + * include a SubscriptionSettings parameter. + */ + QPID_CLIENT_EXTERN const SubscriptionSettings& getDefaultSettings() const; + + /** Get the default settings for subscribe() calls that don't + * include a SubscriptionSettings parameter. + */ + QPID_CLIENT_EXTERN SubscriptionSettings& getDefaultSettings(); + + /** + * Set the default flow control settings for subscribe() calls + * that don't include a SubscriptionSettings parameter. + * + *@param messages: message credit. + *@param bytes: byte credit. + *@param window: if true use window-based flow control. + */ + QPID_CLIENT_EXTERN void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true); + + /** + *Set the default accept-mode for subscribe() calls that don't + *include a SubscriptionSettings parameter. + */ + QPID_CLIENT_EXTERN void setAcceptMode(AcceptMode mode); + + /** + * Set the default acquire-mode subscribe()s that don't specify SubscriptionSettings. + */ + QPID_CLIENT_EXTERN void setAcquireMode(AcquireMode mode); + + QPID_CLIENT_EXTERN void registerFailoverHandler ( boost::function<void ()> fh ); + + QPID_CLIENT_EXTERN Session getSession() const; + + SubscriptionManager(SubscriptionManagerImpl*); ///<@internal + + private: + typedef SubscriptionManagerImpl Impl; + friend class PrivateImplRef<SubscriptionManager>; +}; + +/** AutoCancel cancels a subscription in its destructor */ +class AutoCancel { + public: + AutoCancel(SubscriptionManager& sm_, const std::string& tag_) : sm(sm_), tag(tag_) {} + ~AutoCancel() { sm.cancel(tag); } + private: + SubscriptionManager& sm; + std::string tag; +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_SUBSCRIPTIONMANAGER_H*/ diff --git a/qpid/cpp/include/qpid/client/SubscriptionSettings.h b/qpid/cpp/include/qpid/client/SubscriptionSettings.h new file mode 100644 index 0000000000..b4cb302b56 --- /dev/null +++ b/qpid/cpp/include/qpid/client/SubscriptionSettings.h @@ -0,0 +1,123 @@ +#ifndef QPID_CLIENT_SUBSCRIPTIONSETTINGS_H +#define QPID_CLIENT_SUBSCRIPTIONSETTINGS_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/client/FlowControl.h" +#include "qpid/framing/enum.h" + +namespace qpid { +namespace client { + +/** Bring AMQP enum definitions for message class into this namespace. */ +using namespace qpid::framing::message; + +enum CompletionMode { + MANUAL_COMPLETION = 0, + COMPLETE_ON_DELIVERY = 1, + COMPLETE_ON_ACCEPT = 2 +}; +/** + * Settings for a subscription. + */ +struct SubscriptionSettings +{ + SubscriptionSettings( + FlowControl flow=FlowControl::unlimited(), + AcceptMode accept=ACCEPT_MODE_EXPLICIT, + AcquireMode acquire=ACQUIRE_MODE_PRE_ACQUIRED, + unsigned int autoAck_=1, + CompletionMode completion=COMPLETE_ON_DELIVERY + ) : flowControl(flow), acceptMode(accept), acquireMode(acquire), autoAck(autoAck_), completionMode(completion), exclusive(false) {} + + FlowControl flowControl; ///@< Flow control settings. @see FlowControl + /** + * The acceptMode determines whether the broker should expect + * delivery of messages to be acknowledged by the client + * indicating that it accepts them. A value of + * ACCEPT_MODE_EXPLICIT means that messages must be accepted + * (note: this may be done automatically by the library - see + * autoAck - or through an explicit call be the application - see + * Subscription::accept()) before they can be dequeued. A value of + * ACCEPT_MODE_NONE means that the broker can dequeue a message as + * soon as it is acquired. + */ + AcceptMode acceptMode; ///@< ACCEPT_MODE_EXPLICIT or ACCEPT_MODE_NONE + /** + * The acquireMode determines whether messages are locked for the + * subscriber when delivered, and thus are not delivered to any + * other subscriber unless this subscriber releases them. + * + * The default is ACQUIRE_MODE_PRE_ACQUIRED meaning that the + * subscriber expects to have been given that message exclusively + * (i.e. the message will not be given to any other subscriber + * unless released explicitly or by this subscribers session + * failing without having accepted the message). + * + * Delivery of message in ACQUIRE_MODE_NOT_ACQUIRED mode means the + * message will still be available for other subscribers to + * receive. The application can if desired acquire a (set of) + * messages through an explicit acquire call - see + * Subscription::acquire(). + */ + AcquireMode acquireMode; ///@< ACQUIRE_MODE_PRE_ACQUIRED or ACQUIRE_MODE_NOT_ACQUIRED + + /** + * Configures the frequency at which messages are automatically + * accepted (e.g. a value of 5 means that messages are accepted in + * batches of 5). A value of 0 means no automatic acknowledgement + * will occur and the application will itself be responsible for + * accepting messages. + */ + unsigned int autoAck; + /** + * In windowing mode, completion of a message will cause the + * credit used up by that message to be reallocated. The + * subscriptions completion mode controls how completion is + * managed. + * + * If set to COMPLETE_ON_DELIVERY (which is the default), messages + * will be marked as completed once they have been received. The + * server will be explicitly notified of all completed messages + * for the session when the next accept is sent through the + * subscription (either explictly or through autAck). However the + * server may also periodically request information on the + * completed messages. + * + * If set to COMPLETE_ON_ACCEPT, messages will be marked as + * completed once they are accepted (via the Subscription class) + * and the server will also be notified of all completed messages + * for the session. + * + * If set to MANUAL_COMPLETION the application is responsible for + * completing messages (@see Session::markCompleted()). + */ + CompletionMode completionMode; + /** + * If set, requests that no other subscriber be allowed to access + * the queue while this subscription is active. + */ + bool exclusive; +}; + +}} // namespace qpid::client + +#endif /*!QPID_CLIENT_SUBSCRIPTIONSETTINGS_H*/ diff --git a/qpid/cpp/include/qpid/client/TypedResult.h b/qpid/cpp/include/qpid/client/TypedResult.h new file mode 100644 index 0000000000..8e1a16580c --- /dev/null +++ b/qpid/cpp/include/qpid/client/TypedResult.h @@ -0,0 +1,65 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#ifndef _TypedResult_ +#define _TypedResult_ + +#include "qpid/client/Completion.h" +#include "qpid/framing/StructHelper.h" + +namespace qpid { +namespace client { + +/** + * Returned by asynchronous commands that return a result. + * You can use get() to wait for completion and get the result value. + * \ingroup clientapi + */ +template <class T> class TypedResult : public Completion +{ + T result; + bool decoded; + +public: + ///@internal + TypedResult(const Completion& c) : Completion(c), decoded(false) {} + + /** + * Wait for the asynchronous command that returned this TypedResult to complete + * and return its result. + * + *@return The result returned by the command. + *@exception If the command returns an error, get() throws an exception. + * + */ + T& get() { + if (!decoded) { + framing::StructHelper helper; + helper.decode(result, getResult()); + decoded = true; + } + return result; + } +}; + +}} + +#endif diff --git a/qpid/cpp/include/qpid/console/Agent.h b/qpid/cpp/include/qpid/console/Agent.h new file mode 100644 index 0000000000..629dd71dee --- /dev/null +++ b/qpid/cpp/include/qpid/console/Agent.h @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_AGENT_H_ +#define _QPID_CONSOLE_AGENT_H_ + +#include "qpid/console/Broker.h" +#include "qpid/console/ConsoleImportExport.h" + +namespace qpid { +namespace console { + + /** + * + * \ingroup qmfconsoleapi + */ + class QPID_CONSOLE_CLASS_EXTERN Agent { + public: + typedef std::vector<Agent*> Vector; + + QPID_CONSOLE_INLINE_EXTERN Agent(Broker* _broker, uint32_t _bank, const std::string& _label) : + broker(_broker), brokerBank(broker->getBrokerBank()), + agentBank(_bank), label(_label) {} + QPID_CONSOLE_INLINE_EXTERN Broker* getBroker() const { return broker; } + QPID_CONSOLE_INLINE_EXTERN uint32_t getBrokerBank() const { return brokerBank; } + QPID_CONSOLE_INLINE_EXTERN uint32_t getAgentBank() const { return agentBank; } + QPID_CONSOLE_INLINE_EXTERN const std::string& getLabel() const { return label; } + + private: + Broker* broker; + const uint32_t brokerBank; + const uint32_t agentBank; + const std::string label; + }; + + std::ostream& operator<<(std::ostream& o, const Agent& agent); +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/Broker.h b/qpid/cpp/include/qpid/console/Broker.h new file mode 100644 index 0000000000..c2ba8ac81f --- /dev/null +++ b/qpid/cpp/include/qpid/console/Broker.h @@ -0,0 +1,133 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _QPID_CONSOLE_BROKER_H_ +#define _QPID_CONSOLE_BROKER_H_ + +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/client/Connection.h" +#include "qpid/client/ConnectionSettings.h" +#include "qpid/client/SubscriptionManager.h" +#include "qpid/client/Session.h" +#include "qpid/client/AsyncSession.h" +#include "qpid/client/Message.h" +#include "qpid/client/MessageListener.h" +#include "qpid/sys/Thread.h" +#include "qpid/sys/Runnable.h" +#include "qpid/sys/Mutex.h" +#include "qpid/sys/Condition.h" +#include "qpid/Url.h" +#include "qpid/framing/Buffer.h" +#include "qpid/framing/Uuid.h" +#include <string> +#include <iostream> + +namespace qpid { +namespace console { + class SessionManager; + class Agent; + class Object; + + /** + * + * \ingroup qpidconsoleapi + */ + class Broker : public client::MessageListener { + public: + QPID_CONSOLE_EXTERN Broker(SessionManager& sm, + client::ConnectionSettings& settings); + QPID_CONSOLE_EXTERN ~Broker(); + + QPID_CONSOLE_INLINE_EXTERN bool isConnected() const { return connected; } + QPID_CONSOLE_INLINE_EXTERN const std::string& getError() const { return error; } + QPID_CONSOLE_INLINE_EXTERN const std::string& getSessionId() const { return amqpSessionId; } + QPID_CONSOLE_INLINE_EXTERN const framing::Uuid& getBrokerId() const { return brokerId; } + QPID_CONSOLE_INLINE_EXTERN uint32_t getBrokerBank() const { return 1; } + QPID_CONSOLE_INLINE_EXTERN void addBinding(const std::string& key) { + connThreadBody.bindExchange("qpid.management", key); + } + QPID_CONSOLE_EXTERN std::string getUrl() const; + QPID_CONSOLE_EXTERN void waitForStable(); + + private: + friend class SessionManager; + friend class Object; + typedef std::map<uint64_t,Agent*> AgentMap; + static const int SYNC_TIME = 60; + + SessionManager& sessionManager; + AgentMap agents; + bool connected; + std::string error; + std::string amqpSessionId; + client::ConnectionSettings connectionSettings; + sys::Mutex lock; + sys::Condition cond; + framing::Uuid brokerId; + uint32_t reqsOutstanding; + bool syncInFlight; + bool topicBound; + Object* methodObject; + + friend class ConnectionThread; + class ConnectionThread : public sys::Runnable { + bool operational; + bool shuttingDown; + Broker& broker; + framing::Uuid sessionId; + client::Connection connection; + client::Session session; + client::SubscriptionManager* subscriptions; + std::stringstream queueName; + sys::Mutex connLock; + void run(); + public: + ConnectionThread(Broker& _broker) : + operational(false), shuttingDown(false), broker(_broker), subscriptions(0) {} + ~ConnectionThread(); + void sendBuffer(qpid::framing::Buffer& buf, + uint32_t length, + const std::string& exchange = "qpid.management", + const std::string& routingKey = "broker"); + void bindExchange(const std::string& exchange, const std::string& key); + void shutdown(); + }; + + ConnectionThread connThreadBody; + sys::Thread connThread; + + void encodeHeader(framing::Buffer& buf, uint8_t opcode, uint32_t seq = 0) const; + bool checkHeader(framing::Buffer& buf, uint8_t *opcode, uint32_t *seq) const; + void received(client::Message& msg); + void resetAgents(); + void updateAgent(const Object& object); + void incOutstanding(); + void decOutstanding(); + void setBrokerId(const framing::Uuid& id) { brokerId = id; } + void appendAgents(std::vector<Agent*>& agents) const; + + friend std::ostream& operator<<(std::ostream& o, const Broker& k); + }; + + std::ostream& operator<<(std::ostream& o, const Broker& k); +} +} + +#endif diff --git a/qpid/cpp/include/qpid/console/ClassKey.h b/qpid/cpp/include/qpid/console/ClassKey.h new file mode 100644 index 0000000000..95cd2627f1 --- /dev/null +++ b/qpid/cpp/include/qpid/console/ClassKey.h @@ -0,0 +1,66 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_CLASSKEY_H_ +#define _QPID_CONSOLE_CLASSKEY_H_ + +#include <string> +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/console/Package.h" +#include "qpid/framing/Buffer.h" + +namespace qpid { +namespace console { + + /** + * + * \ingroup qmfconsoleapi + */ + class QPID_CONSOLE_EXTERN ClassKey { + public: + static const int HASH_SIZE = 16; + + ClassKey(const std::string& package, const std::string& name, const uint8_t* hash); + + const std::string& getPackageName() const { return package; } + const std::string& getClassName() const { return name; } + const uint8_t* getHash() const { return hash; } + std::string getHashString() const; + std::string str() const; + bool operator==(const ClassKey& other) const; + bool operator!=(const ClassKey& other) const; + bool operator<(const ClassKey& other) const; + bool operator>(const ClassKey& other) const; + bool operator<=(const ClassKey& other) const; + bool operator>=(const ClassKey& other) const; + void encode(framing::Buffer& buffer) const; + + private: + std::string package; + std::string name; + uint8_t hash[HASH_SIZE]; + }; + + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ClassKey& k); +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/ConsoleImportExport.h b/qpid/cpp/include/qpid/console/ConsoleImportExport.h new file mode 100644 index 0000000000..aac30858f7 --- /dev/null +++ b/qpid/cpp/include/qpid/console/ConsoleImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_CONSOLE_IMPORT_EXPORT_H +#define QPID_CONSOLE_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. + */ + +#include "qpid/ImportExport.h" + +#if defined(CONSOLE_EXPORT) || defined (qmfconsole_EXPORTS) +# define QPID_CONSOLE_EXTERN QPID_EXPORT +# define QPID_CONSOLE_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_CONSOLE_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_CONSOLE_EXTERN QPID_IMPORT +# define QPID_CONSOLE_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_CONSOLE_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif diff --git a/qpid/cpp/include/qpid/console/ConsoleListener.h b/qpid/cpp/include/qpid/console/ConsoleListener.h new file mode 100644 index 0000000000..7a649da657 --- /dev/null +++ b/qpid/cpp/include/qpid/console/ConsoleListener.h @@ -0,0 +1,97 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_CONSOLE_LISTENER_H_ +#define _QPID_CONSOLE_CONSOLE_LISTENER_H_ + +#include <string> +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/console/Broker.h" +#include "qpid/console/ClassKey.h" +#include "qpid/console/Object.h" +#include "qpid/console/Event.h" + +namespace qpid { +namespace console { + + /** + * Implement a subclass of ConsoleListener and subscribe it using + * the SessionManager to receive indications. + * + * \ingroup qmfconsoleapi + */ + class QPID_CONSOLE_EXTERN ConsoleListener{ + public: + virtual ~ConsoleListener() {}; + + /** Invoked when a connection is established to a broker + */ + virtual void brokerConnected(const Broker&) {} + + /** Invoked when the connection to a broker is lost + */ + virtual void brokerDisconnected(const Broker&) {} + + /** Invoked when a QMF package is discovered. + */ + virtual void newPackage(const std::string&) {} + + /** Invoked when a new class is discovered. Session.getSchema can be + * used to obtain details about the class. + */ + virtual void newClass(const ClassKey&) {} + + /** Invoked when a QMF agent is discovered. + */ + virtual void newAgent(const Agent&) {} + + /** Invoked when a QMF agent disconects. + */ + virtual void delAgent(const Agent&) {} + + /** Invoked when an object is updated. + */ + virtual void objectProps(Broker&, Object&) {} + + /** Invoked when an object is updated. + */ + virtual void objectStats(Broker&, Object&) {} + + /** Invoked when an event is raised. + */ + virtual void event(Event&) {} + + /** + */ + //virtual void heartbeat(Agent&, uint64_t) {} + + /** + */ + virtual void brokerInfo(Broker&) {} + + /** + */ + //virtual void methodResponse(Broker&, uint32_t seq, MethodResponse&) {} + }; +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/Event.h b/qpid/cpp/include/qpid/console/Event.h new file mode 100644 index 0000000000..ef4ecc791c --- /dev/null +++ b/qpid/cpp/include/qpid/console/Event.h @@ -0,0 +1,86 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_EVENT_H_ +#define _QPID_CONSOLE_EVENT_H_ + +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/console/Object.h" +#include "qpid/framing/Uuid.h" +#include "qpid/framing/FieldTable.h" + +namespace qpid { +namespace framing { + class Buffer; +} +namespace console { + + class Broker; + struct SchemaClass; + class ClassKey; + + /** + * + * \ingroup qmfconsoleapi + */ + class Event { + public: + typedef enum { + SEV_EMERGENCY = 0, SEV_ALERT = 1, SEV_CRITICAL = 2, SEV_ERROR = 3, + SEV_WARNING = 4, SEV_NOTICE = 5, SEV_INFO = 6, SEV_DEBUG = 7 + } Severity; + + QPID_CONSOLE_EXTERN Event(Broker* broker, + SchemaClass* schemaClass, + framing::Buffer& buffer); + Broker* getBroker() const { return broker; } + QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const; + SchemaClass* getSchema() const { return schema; } + const Object::AttributeMap& getAttributes() const { return attributes; } + uint64_t getTimestamp() const { return timestamp; } + uint8_t getSeverity() const { return severity; } + QPID_CONSOLE_EXTERN std::string getSeverityString() const; + + QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const; + QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const; + QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const; + QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const; + QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const; + QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const; + QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const; + QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const; + QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const; + + private: + Broker* broker; + SchemaClass* schema; + uint64_t timestamp; + Severity severity; + Object::AttributeMap attributes; + }; + + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Event& event); +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/Object.h b/qpid/cpp/include/qpid/console/Object.h new file mode 100644 index 0000000000..5a29fdf792 --- /dev/null +++ b/qpid/cpp/include/qpid/console/Object.h @@ -0,0 +1,123 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _QPID_CONSOLE_OBJECT_H_ +#define _QPID_CONSOLE_OBJECT_H_ + +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/console/ObjectId.h" +#include "qpid/framing/Uuid.h" +#include "qpid/framing/FieldTable.h" +#include <boost/shared_ptr.hpp> +#include <map> +#include <set> +#include <vector> + +namespace qpid { +namespace framing { + class Buffer; +} +namespace console { + + class Broker; + struct SchemaClass; + struct SchemaMethod; + class ObjectId; + class ClassKey; + class Value; + + /** + * \ingroup qmfconsoleapi + */ + struct MethodResponse { + uint32_t code; + std::string text; + std::map<std::string, boost::shared_ptr<Value> > arguments; + }; + + class Object { + public: + typedef std::vector<Object> Vector; + struct AttributeMap : public std::map<std::string, boost::shared_ptr<Value> > { + QPID_CONSOLE_EXTERN void addRef(const std::string& key, const ObjectId& val); + QPID_CONSOLE_EXTERN void addUint(const std::string& key, uint32_t val); + QPID_CONSOLE_EXTERN void addInt(const std::string& key, int32_t val); + QPID_CONSOLE_EXTERN void addUint64(const std::string& key, uint64_t val); + QPID_CONSOLE_EXTERN void addInt64(const std::string& key, int64_t val); + QPID_CONSOLE_EXTERN void addString(const std::string& key, const std::string& val); + QPID_CONSOLE_EXTERN void addBool(const std::string& key, bool val); + QPID_CONSOLE_EXTERN void addFloat(const std::string& key, float val); + QPID_CONSOLE_EXTERN void addDouble(const std::string& key, double val); + QPID_CONSOLE_EXTERN void addUuid(const std::string& key, const framing::Uuid& val); + QPID_CONSOLE_EXTERN void addMap(const std::string& key, const framing::FieldTable& val); + }; + + QPID_CONSOLE_EXTERN Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat); + QPID_CONSOLE_EXTERN ~Object(); + + Broker* getBroker() const { return broker; } + const ObjectId& getObjectId() const { return objectId; } + QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const; + SchemaClass* getSchema() const { return schema; } + uint64_t getCurrentTime() const { return currentTime; } + uint64_t getCreateTime() const { return createTime; } + uint64_t getDeleteTime() const { return deleteTime; } + bool isDeleted() const { return deleteTime != 0; } + QPID_CONSOLE_EXTERN std::string getIndex() const; + QPID_CONSOLE_EXTERN void mergeUpdate(const Object& updated); + const AttributeMap& getAttributes() const { return attributes; } + QPID_CONSOLE_EXTERN void invokeMethod(const std::string name, + const AttributeMap& args, + MethodResponse& result); + QPID_CONSOLE_EXTERN void handleMethodResp(framing::Buffer& buffer, + uint32_t sequence); + + QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const; + QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const; + QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const; + QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const; + QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const; + QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const; + QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const; + QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const; + QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const; + QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const; + + private: + Broker* broker; + SchemaClass* schema; + ObjectId objectId; + uint64_t currentTime; + uint64_t createTime; + uint64_t deleteTime; + AttributeMap attributes; + SchemaMethod* pendingMethod; + MethodResponse methodResponse; + + void parsePresenceMasks(framing::Buffer& buffer, std::set<std::string>& excludeList); + }; + + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Object& object); +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/ObjectId.h b/qpid/cpp/include/qpid/console/ObjectId.h new file mode 100644 index 0000000000..7904c85598 --- /dev/null +++ b/qpid/cpp/include/qpid/console/ObjectId.h @@ -0,0 +1,69 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_OBJECTID_H +#define _QPID_CONSOLE_OBJECTID_H + +#include <iostream> +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/sys/IntegerTypes.h" + +namespace qpid { +namespace framing { + class Buffer; +} +namespace console { + + /** + * + * \ingroup qmfconsoleapi + */ + class QPID_CONSOLE_EXTERN ObjectId { + public: + ObjectId() : first(0), second(0) {} + ObjectId(framing::Buffer& buffer); + + uint8_t getFlags() const { return (first & 0xF000000000000000LL) >> 60; } + uint16_t getSequence() const { return (first & 0x0FFF000000000000LL) >> 48; } + uint32_t getBrokerBank() const { return (first & 0x0000FFFFF0000000LL) >> 28; } + uint32_t getAgentBank() const { return first & 0x000000000FFFFFFFLL; } + uint64_t getObject() const { return second; } + bool isDurable() const { return getSequence() == 0; } + void decode(framing::Buffer& buffer); + void encode(framing::Buffer& buffer); + void setValue(uint64_t f, uint64_t s) { first = f; second = s; } + + bool operator==(const ObjectId& other) const; + bool operator!=(const ObjectId& other) const; + bool operator<(const ObjectId& other) const; + bool operator>(const ObjectId& other) const; + bool operator<=(const ObjectId& other) const; + bool operator>=(const ObjectId& other) const; + + private: + uint64_t first; + uint64_t second; + }; + + QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ObjectId& id); +} +} + +#endif diff --git a/qpid/cpp/include/qpid/console/Package.h b/qpid/cpp/include/qpid/console/Package.h new file mode 100644 index 0000000000..3b59e366ff --- /dev/null +++ b/qpid/cpp/include/qpid/console/Package.h @@ -0,0 +1,78 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_PACKAGE_H_ +#define _QPID_CONSOLE_PACKAGE_H_ + +#include <string> +#include <map> +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/sys/IntegerTypes.h" + +namespace qpid { +namespace console { + struct SchemaClass; + + /** + * + * \ingroup qmfconsoleapi + */ + class Package { + public: + Package(const std::string& n) : name(n) {} + const std::string& getName() const { return name; } + + private: + friend class SessionManager; + struct NameHash { + std::string name; + uint8_t hash[16]; + NameHash(const std::string& n, const uint8_t* h) : name(n) { + for (int i = 0; i < 16; i++) + hash[i] = h[i]; + } + }; + + struct NameHashComp { + bool operator() (const NameHash& lhs, const NameHash& rhs) const + { + if (lhs.name != rhs.name) + return lhs.name < rhs.name; + else + for (int i = 0; i < 16; i++) + if (lhs.hash[i] != rhs.hash[i]) + return lhs.hash[i] < rhs.hash[i]; + return false; + } + }; + + typedef std::map<NameHash, SchemaClass*, NameHashComp> ClassMap; + + const std::string name; + ClassMap classes; + + SchemaClass* getClass(const std::string& className, uint8_t* hash); + void addClass(const std::string& className, uint8_t* hash, + SchemaClass* schemaClass); + }; +} +} + +#endif diff --git a/qpid/cpp/include/qpid/console/Schema.h b/qpid/cpp/include/qpid/console/Schema.h new file mode 100644 index 0000000000..6d4e41ab3e --- /dev/null +++ b/qpid/cpp/include/qpid/console/Schema.h @@ -0,0 +1,105 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _QPID_CONSOLE_SCHEMA_H_ +#define _QPID_CONSOLE_SCHEMA_H_ + +#include "qpid/console/ClassKey.h" +#include <boost/shared_ptr.hpp> +#include <vector> + +namespace qpid { +namespace framing { + class Buffer; +} +namespace console { + class Value; + + struct SchemaArgument { + SchemaArgument(framing::Buffer& buffer, bool forMethod = false); + boost::shared_ptr<Value> decodeValue(framing::Buffer& buffer); + + std::string name; + uint8_t typeCode; + bool dirInput; + bool dirOutput; + std::string unit; + int min; + int max; + int maxLen; + std::string desc; + std::string defaultVal; + }; + + struct SchemaProperty { + SchemaProperty(framing::Buffer& buffer); + boost::shared_ptr<Value> decodeValue(framing::Buffer& buffer); + + std::string name; + uint8_t typeCode; + uint8_t accessCode; + bool isIndex; + bool isOptional; + std::string unit; + int min; + int max; + int maxLen; + std::string desc; + }; + + struct SchemaStatistic { + SchemaStatistic(framing::Buffer& buffer); + boost::shared_ptr<Value> decodeValue(framing::Buffer& buffer); + + std::string name; + uint8_t typeCode; + std::string unit; + std::string desc; + }; + + struct SchemaMethod { + SchemaMethod(framing::Buffer& buffer); + ~SchemaMethod(); + + std::string name; + std::string desc; + std::vector<SchemaArgument*> arguments; + }; + + struct SchemaClass { + static const uint8_t KIND_TABLE = 1; + static const uint8_t KIND_EVENT = 2; + + SchemaClass(const uint8_t kind, const ClassKey& key, framing::Buffer& buffer); + ~SchemaClass(); + const ClassKey& getClassKey() const { return key; } + + const uint8_t kind; + const ClassKey key; + std::vector<SchemaProperty*> properties; + std::vector<SchemaStatistic*> statistics; + std::vector<SchemaMethod*> methods; + std::vector<SchemaArgument*> arguments; + }; +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/SequenceManager.h b/qpid/cpp/include/qpid/console/SequenceManager.h new file mode 100644 index 0000000000..ea0ccf3f77 --- /dev/null +++ b/qpid/cpp/include/qpid/console/SequenceManager.h @@ -0,0 +1,54 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _QPID_CONSOLE_SEQUENCEMANAGER_H_ +#define _QPID_CONSOLE_SEQUENCEMANAGER_H_ + +#include "qpid/console/ConsoleImportExport.h" +#include "qpid/sys/Mutex.h" +#include <map> +#include <string> +#include <set> + +namespace qpid { +namespace console { + + /** + * + * \ingroup qpidconsoleapi + */ + class SequenceManager { + public: + typedef std::set<uint32_t> set; + + SequenceManager() : sequence(0) {} + QPID_CONSOLE_EXTERN uint32_t reserve(const std::string& context = ""); + QPID_CONSOLE_EXTERN std::string release(uint32_t seq); + + private: + sys::Mutex lock; + uint32_t sequence; + std::map<uint32_t, std::string> pending; + }; +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/console/SessionManager.h b/qpid/cpp/include/qpid/console/SessionManager.h new file mode 100644 index 0000000000..b46af549ff --- /dev/null +++ b/qpid/cpp/include/qpid/console/SessionManager.h @@ -0,0 +1,219 @@ +#ifndef _QPID_CONSOLE_SESSION_MANAGER_H +#define _QPID_CONSOLE_SESSION_MANAGER_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/console/ConsoleImportExport.h" +#include "qpid/console/Broker.h" +#include "qpid/console/Package.h" +#include "qpid/console/SequenceManager.h" +#include "qpid/console/ClassKey.h" +#include "qpid/console/Schema.h" +#include "qpid/console/Agent.h" +#include "qpid/console/Object.h" +#include "qpid/console/ObjectId.h" +#include "qpid/console/Value.h" +#include "qpid/sys/Mutex.h" +#include "qpid/sys/Condition.h" +#include "qpid/client/ConnectionSettings.h" +#include <string> +#include <vector> + +namespace qpid { +namespace console { + +class ConsoleListener; + +/** + * + * \ingroup qmfconsoleapi + */ +class SessionManager +{ + public: + typedef std::vector<std::string> NameVector; + typedef std::vector<ClassKey> KeyVector; + QPID_CONSOLE_EXTERN ~SessionManager(); + + struct Settings { + bool rcvObjects; + bool rcvEvents; + bool rcvHeartbeats; + bool userBindings; + uint32_t methodTimeout; + uint32_t getTimeout; + + Settings() : rcvObjects(true), rcvEvents(true), rcvHeartbeats(true), + userBindings(false), methodTimeout(20), getTimeout(20) + {} + }; + + /** Create a new SessionManager + * + * Provide your own subclass of ConsoleListener to receive updates and indications + * asynchronously or leave it as its default and use only synchronous methods. + * + *@param listener Listener object to receive asynchronous indications. + *@param settings.rcvObjects Listener wishes to receive managed object data. + *@param settings.rcvEvents Listener wishes to receive events. + *@param settings.rcvHeartbeats Listener wishes to receive agent heartbeats. + *@param settings.userBindings If rcvObjects is true, userBindings allows the + * console client to control which object classes are received. See the bindPackage + * and bindClass methods. If userBindings is false, the listener will receive + * updates for all object classes. + */ + QPID_CONSOLE_EXTERN SessionManager(ConsoleListener* listener = 0, + Settings settings = Settings()); + + /** Connect a broker to the console session + * + *@param settings Connection settings for client access + *@return broker object if operation is successful + * an exception shall be thrown. + */ + QPID_CONSOLE_EXTERN Broker* addBroker(client::ConnectionSettings& settings); + + /** Disconnect a broker from the console session + * + *@param broker The broker object returned from an earlier call to addBroker. + */ + QPID_CONSOLE_EXTERN void delBroker(Broker* broker); + + /** Get a list of known management packages + * + *@param packages Vector of package names returned by the session manager. + */ + QPID_CONSOLE_EXTERN void getPackages(NameVector& packages); + + /** Get a list of class keys associated with a package + * + *@param classKeys List of class keys returned by the session manager. + *@param packageName Name of package being queried. + */ + QPID_CONSOLE_EXTERN void getClasses(KeyVector& classKeys, + const std::string& packageName); + + /** Get the schema of a class given its class key + * + *@param classKey Class key of the desired schema. + */ + QPID_CONSOLE_EXTERN SchemaClass& getSchema(const ClassKey& classKey); + + /** Request that updates be received for all classes within a package + * + * Note that this method is only meaningful if a ConsoleListener was provided at session + * creation and if the 'userBindings' flag was set to true. + * + *@param packageName Name of the package to which to bind. + */ + QPID_CONSOLE_EXTERN void bindPackage(const std::string& packageName); + + /** Request update to be received for a particular class + * + * Note that this method is only meaningful if a ConsoleListener was provided at session + * creation and if the 'userBindings' flag was set to true. + * + *@param classKey Class key of class to which to bind. + */ + QPID_CONSOLE_EXTERN void bindClass(const ClassKey& classKey); + QPID_CONSOLE_EXTERN void bindClass(const std::string& packageName, + const std::string& className); + + /** Request events from a particular package. + * + * Note that this method is only meaningful if a ConsoleListener was provided at session + * creation and if the 'userBindings' flag was set to true. + * + * @param classKey Class key of event of interest + * @param packageName Name of package of event of interest. + * @param eventName Name of event of interest. Default=All events defined by package. + */ + QPID_CONSOLE_EXTERN void bindEvent(const ClassKey& classKey); + QPID_CONSOLE_EXTERN void bindEvent(const std::string& packageName, + const std::string& eventName=""); + + + /** Get a list of qmf agents known to the session manager. + * + *@param agents Vector of Agent objects returned by the session manager. + *@param broker Return agents registered with this broker only. If NULL, return agents + * from all connected brokers. + */ + QPID_CONSOLE_EXTERN void getAgents(Agent::Vector& agents, + Broker* broker = 0); + + /** Get objects from agents. There are four variants of this method with different ways of + * specifying from which class objects are being queried. + * + *@param objects List of objects received. + *@param classKey ClassKey object identifying class to be queried. + *@param className Class name identifying class to be queried. + *@param objectId Object Id of the single object to be queried. + *@param broker Restrict the query to this broker, or all brokers if NULL. + *@param agent Restrict the query to this agent, or all agents if NULL. + */ + QPID_CONSOLE_EXTERN void getObjects(Object::Vector& objects, + const std::string& className, + Broker* broker = 0, + Agent* agent = 0); + //void getObjects(Object::Vector& objects, const ClassKey& classKey, + // Broker* broker = 0, Agent* agent = 0); + //void getObjects(Object::Vector& objects, const ObjectId& objectId, + // Broker* broker = 0, Agent* agent = 0); + +private: + friend class Broker; + friend class Broker::ConnectionThread; + friend class Object; + sys::Mutex lock; + sys::Mutex brokerListLock; + ConsoleListener* listener; + std::vector<Broker*> brokers; + std::map<std::string, Package*> packages; + SequenceManager sequenceManager; + sys::Condition cv; + SequenceManager::set syncSequenceList; + Object::Vector getResult; + std::string error; + Settings settings; + NameVector bindingKeyList; + + void bindingKeys(); + void allBrokersStable(); + void startProtocol(Broker* broker); + void handleBrokerResp(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handlePackageInd(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleCommandComplete(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleClassInd(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleMethodResp(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleHeartbeatInd(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleEventInd(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleSchemaResp(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence); + void handleContentInd(Broker* broker, framing::Buffer& inBuffer, uint32_t sequence, bool prop, bool stat); + void handleBrokerConnect(Broker* broker); + void handleBrokerDisconnect(Broker* broker); + +}; + +}} // namespace qpid::console + +#endif /*!_QPID_CONSOLE_SESSION_MANAGER_H*/ diff --git a/qpid/cpp/include/qpid/console/Value.h b/qpid/cpp/include/qpid/console/Value.h new file mode 100644 index 0000000000..d9eb65053b --- /dev/null +++ b/qpid/cpp/include/qpid/console/Value.h @@ -0,0 +1,213 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _QPID_CONSOLE_VALUE_H_ +#define _QPID_CONSOLE_VALUE_H_ + +#include "qpid/Exception.h" +#include "qpid/framing/Uuid.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/console/ObjectId.h" +#include <boost/shared_ptr.hpp> + +namespace qpid { +namespace framing { + class Buffer; +} +namespace console { + + /** + * \ingroup qmfconsoleapi + */ + class Value { + + public: + typedef boost::shared_ptr<Value> Ptr; + virtual ~Value() {} + virtual std::string str() const = 0; + + virtual bool isNull() const { return false; } + virtual bool isObjectId() const { return false; } + virtual bool isUint() const { return false; } + virtual bool isInt() const { return false; } + virtual bool isUint64() const { return false; } + virtual bool isInt64() const { return false; } + virtual bool isString() const { return false; } + virtual bool isBool() const { return false; } + virtual bool isFloat() const { return false; } + virtual bool isDouble() const { return false; } + virtual bool isUuid() const { return false; } + virtual bool isMap() const { return false; } + + virtual ObjectId asObjectId() const { incompatible(); return ObjectId(); } + virtual uint32_t asUint() const { incompatible(); return 0; } + virtual int32_t asInt() const { incompatible(); return 0; } + virtual uint64_t asUint64() const { incompatible(); return 0; } + virtual int64_t asInt64() const { incompatible(); return 0; } + virtual std::string asString() const { incompatible(); return std::string(); } + virtual bool asBool() const { incompatible(); return false; } + virtual float asFloat() const { incompatible(); return 0.0; } + virtual double asDouble() const { incompatible(); return 0.0; } + virtual framing::Uuid asUuid() const { incompatible(); return framing::Uuid(); } + virtual framing::FieldTable asMap() const { incompatible(); return framing::FieldTable(); } + + private: + void incompatible() const { + throw Exception("Incompatible Type"); + } + }; + + class NullValue : public Value { + public: + NullValue() {} + std::string str() const; + bool isNull() const { return true; } + }; + + class RefValue : public Value { + public: + RefValue(ObjectId v) : value(v) {} + RefValue(framing::Buffer& buffer); + std::string str() const; + bool isObjectId() const { return true; } + ObjectId asObjectId() const { return value; } + private: + ObjectId value; + }; + + class UintValue : public Value { + public: + UintValue(uint32_t v) : value(v) {} + std::string str() const; + bool isUint() const { return true; } + uint32_t asUint() const { return value; } + bool isUint64() const { return true; } + uint64_t asUint64() const { return (uint64_t) value; } + private: + uint32_t value; + }; + + class IntValue : public Value { + public: + IntValue(int32_t v) : value(v) {} + std::string str() const; + bool isInt() const { return true; } + int32_t asInt() const { return value; } + bool isInt64() const { return true; } + int64_t asInt64() const { return (int64_t) value; } + private: + int32_t value; + }; + + class Uint64Value : public Value { + public: + Uint64Value(uint64_t v) : value(v) {} + std::string str() const; + bool isUint64() const { return true; } + uint64_t asUint64() const { return value; } + private: + uint64_t value; + }; + + class Int64Value : public Value { + public: + Int64Value(int64_t v) : value(v) {} + std::string str() const; + bool isInt64() const { return true; } + int64_t asInt64() const { return value; } + private: + int64_t value; + }; + + class StringValue : public Value { + public: + StringValue(const std::string& v) : value(v) {} + StringValue(framing::Buffer& buffer, int tc); + std::string str() const { return value; } + bool isString() const { return true; } + std::string asString() const { return value; } + private: + std::string value; + }; + + class BoolValue : public Value { + public: + BoolValue(bool v) : value(v) {} + BoolValue(uint8_t v) : value(v != 0) {} + std::string str() const; + bool isBool() const { return true; } + bool asBool() const { return value; } + private: + bool value; + }; + + class FloatValue : public Value { + public: + FloatValue(float v) : value(v) {} + std::string str() const; + bool isFloat() const { return true; } + float asFloat() const { return value; } + bool isDouble() const { return true; } + double asDouble() const { return (double) value; } + private: + float value; + }; + + class DoubleValue : public Value { + public: + DoubleValue(double v) : value(v) {} + std::string str() const; + bool isDouble() const { return true; } + double asDouble() const { return value; } + private: + double value; + }; + + class UuidValue : public Value { + public: + UuidValue(const framing::Uuid& v) : value(v) {} + UuidValue(framing::Buffer& buffer); + std::string str() const { return value.str(); } + bool isUuid() const { return true; } + framing::Uuid asUuid() const { return value; } + private: + framing::Uuid value; + }; + + class MapValue : public Value { + public: + MapValue(const framing::FieldTable& v) : value(v) {} + MapValue(framing::Buffer& buffer); + std::string str() const; + bool isMap() const { return true; } + framing::FieldTable asMap() const { return value; } + private: + framing::FieldTable value; + }; + + class ValueFactory { + public: + static Value::Ptr newValue(int typeCode, framing::Buffer& buffer); + static void encodeValue(int typeCode, Value::Ptr value, framing::Buffer& buffer); + }; +} +} + +#endif diff --git a/qpid/cpp/include/qpid/framing/Array.h b/qpid/cpp/include/qpid/framing/Array.h new file mode 100644 index 0000000000..1e97be3bb4 --- /dev/null +++ b/qpid/cpp/include/qpid/framing/Array.h @@ -0,0 +1,97 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#include "qpid/framing/amqp_types.h" +#include "qpid/framing/FieldValue.h" +#include "qpid/framing/TypeCode.h" +#include <boost/shared_ptr.hpp> +#include <iostream> +#include <vector> +#include "qpid/CommonImportExport.h" + +#ifndef _Array_ +#define _Array_ + +namespace qpid { +namespace framing { + +class Buffer; + +class QPID_COMMON_CLASS_EXTERN Array +{ + public: + typedef boost::shared_ptr<FieldValue> ValuePtr; + typedef std::vector<ValuePtr> ValueVector; + typedef ValueVector::const_iterator const_iterator; + typedef ValueVector::iterator iterator; + + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer); + + QPID_COMMON_EXTERN int count() const; + QPID_COMMON_EXTERN bool operator==(const Array& other) const; + + QPID_COMMON_EXTERN Array(); + QPID_COMMON_EXTERN Array(TypeCode type); + QPID_COMMON_EXTERN Array(uint8_t type); + //creates a longstr array + QPID_COMMON_EXTERN Array(const std::vector<std::string>& in); + + QPID_COMMON_INLINE_EXTERN TypeCode getType() const { return type; } + + // std collection interface. + QPID_COMMON_INLINE_EXTERN const_iterator begin() const { return values.begin(); } + QPID_COMMON_INLINE_EXTERN const_iterator end() const { return values.end(); } + QPID_COMMON_INLINE_EXTERN iterator begin() { return values.begin(); } + QPID_COMMON_INLINE_EXTERN iterator end(){ return values.end(); } + + QPID_COMMON_INLINE_EXTERN ValuePtr front() const { return values.front(); } + QPID_COMMON_INLINE_EXTERN ValuePtr back() const { return values.back(); } + QPID_COMMON_INLINE_EXTERN size_t size() const { return values.size(); } + + QPID_COMMON_EXTERN void insert(iterator i, ValuePtr value); + QPID_COMMON_INLINE_EXTERN void erase(iterator i) { values.erase(i); } + QPID_COMMON_INLINE_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); } + QPID_COMMON_INLINE_EXTERN void pop_back() { values.pop_back(); } + + // Non-std interface + QPID_COMMON_INLINE_EXTERN void add(ValuePtr value) { push_back(value); } + + template <class T> + void collect(std::vector<T>& out) const + { + for (ValueVector::const_iterator i = values.begin(); i != values.end(); ++i) { + out.push_back((*i)->get<T>()); + } + } + + private: + TypeCode type; + ValueVector values; + + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const Array& body); +}; + +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/framing/Buffer.h b/qpid/cpp/include/qpid/framing/Buffer.h new file mode 100644 index 0000000000..8b08e60762 --- /dev/null +++ b/qpid/cpp/include/qpid/framing/Buffer.h @@ -0,0 +1,136 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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/Exception.h" +#include "qpid/CommonImportExport.h" +#include <boost/iterator/iterator_facade.hpp> + +#ifndef _Buffer_ +#define _Buffer_ + +namespace qpid { +namespace framing { + +struct QPID_COMMON_CLASS_EXTERN OutOfBounds : qpid::Exception { + OutOfBounds() : qpid::Exception(std::string("Out of Bounds")) {} +}; + +class Content; +class FieldTable; + +class QPID_COMMON_CLASS_EXTERN Buffer +{ + uint32_t size; + char* data; + uint32_t position; + uint32_t r_position; + + public: + void checkAvailable(uint32_t count) { if (position + count > size) throw OutOfBounds(); } + + /** Buffer input/output iterator. + * Supports using an amqp_0_10::Codec with a framing::Buffer. + */ + class Iterator : public boost::iterator_facade< + Iterator, char, boost::random_access_traversal_tag> + { + public: + Iterator(Buffer& b) : buffer(&b) {} + + private: + friend class boost::iterator_core_access; + char& dereference() const { return buffer->data[buffer->position]; } + void increment() { ++buffer->position; } + bool equal(const Iterator& x) const { return buffer == x.buffer; } + + Buffer* buffer; + }; + + friend class Iterator; + + QPID_COMMON_EXTERN Buffer(char* data=0, uint32_t size=0); + + QPID_COMMON_EXTERN void record(); + QPID_COMMON_EXTERN void restore(bool reRecord = false); + QPID_COMMON_EXTERN void reset(); + + QPID_COMMON_INLINE_EXTERN uint32_t available() { return size - position; } + QPID_COMMON_INLINE_EXTERN uint32_t getSize() { return size; } + QPID_COMMON_INLINE_EXTERN uint32_t getPosition() { return position; } + QPID_COMMON_INLINE_EXTERN void setPosition(uint32_t p) { position = p; } + QPID_COMMON_INLINE_EXTERN Iterator getIterator() { return Iterator(*this); } + QPID_COMMON_INLINE_EXTERN char* getPointer() { return data; } + + QPID_COMMON_EXTERN void putOctet(uint8_t i); + QPID_COMMON_EXTERN void putShort(uint16_t i); + QPID_COMMON_EXTERN void putLong(uint32_t i); + QPID_COMMON_EXTERN void putLongLong(uint64_t i); + QPID_COMMON_EXTERN void putInt8(int8_t i); + QPID_COMMON_EXTERN void putInt16(int16_t i); + QPID_COMMON_EXTERN void putInt32(int32_t i); + QPID_COMMON_EXTERN void putInt64(int64_t i); + QPID_COMMON_EXTERN void putFloat(float f); + QPID_COMMON_EXTERN void putDouble(double f); + QPID_COMMON_EXTERN void putBin128(const uint8_t* b); + + QPID_COMMON_EXTERN uint8_t getOctet(); + QPID_COMMON_EXTERN uint16_t getShort(); + QPID_COMMON_EXTERN uint32_t getLong(); + QPID_COMMON_EXTERN uint64_t getLongLong(); + QPID_COMMON_EXTERN int8_t getInt8(); + QPID_COMMON_EXTERN int16_t getInt16(); + QPID_COMMON_EXTERN int32_t getInt32(); + QPID_COMMON_EXTERN int64_t getInt64(); + QPID_COMMON_EXTERN float getFloat(); + QPID_COMMON_EXTERN double getDouble(); + + template <int n> + QPID_COMMON_EXTERN uint64_t getUInt(); + + template <int n> + QPID_COMMON_EXTERN void putUInt(uint64_t); + + QPID_COMMON_EXTERN void putShortString(const string& s); + QPID_COMMON_EXTERN void putMediumString(const string& s); + QPID_COMMON_EXTERN void putLongString(const string& s); + QPID_COMMON_EXTERN void getShortString(string& s); + QPID_COMMON_EXTERN void getMediumString(string& s); + QPID_COMMON_EXTERN void getLongString(string& s); + QPID_COMMON_EXTERN void getBin128(uint8_t* b); + + QPID_COMMON_EXTERN void putRawData(const string& s); + QPID_COMMON_EXTERN void getRawData(string& s, uint32_t size); + + QPID_COMMON_EXTERN void putRawData(const uint8_t* data, size_t size); + QPID_COMMON_EXTERN void getRawData(uint8_t* data, size_t size); + + template <class T> void put(const T& data) { data.encode(*this); } + template <class T> void get(T& data) { data.decode(*this); } + + QPID_COMMON_EXTERN void dump(std::ostream&) const; +}; + +std::ostream& operator<<(std::ostream&, const Buffer&); + +}} // namespace qpid::framing + + +#endif diff --git a/qpid/cpp/include/qpid/framing/FieldTable.h b/qpid/cpp/include/qpid/framing/FieldTable.h new file mode 100644 index 0000000000..fed431129a --- /dev/null +++ b/qpid/cpp/include/qpid/framing/FieldTable.h @@ -0,0 +1,129 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#include <iostream> +#include <vector> +#include <boost/shared_ptr.hpp> +#include <map> +#include "qpid/framing/amqp_types.h" +#include "qpid/CommonImportExport.h" + +#ifndef _FieldTable_ +#define _FieldTable_ + +namespace qpid { + /** + * The framing namespace contains classes that are used to create, + * send and receive the basic packets from which AMQP is built. + */ +namespace framing { + +class Array; +class FieldValue; +class Buffer; + +/** + * A set of name-value pairs. (See the AMQP spec for more details on + * AMQP field tables). + * + * \ingroup clientapi + */ +class FieldTable +{ + public: + typedef boost::shared_ptr<FieldValue> ValuePtr; + typedef std::map<std::string, ValuePtr> ValueMap; + typedef ValueMap::iterator iterator; + typedef ValueMap::const_iterator const_iterator; + typedef ValueMap::const_reference const_reference; + typedef ValueMap::reference reference; + typedef ValueMap::value_type value_type; + + QPID_COMMON_INLINE_EXTERN FieldTable() {}; + QPID_COMMON_EXTERN FieldTable(const FieldTable& ft); + QPID_COMMON_EXTERN ~FieldTable(); + QPID_COMMON_EXTERN FieldTable& operator=(const FieldTable& ft); + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer); + + QPID_COMMON_EXTERN int count() const; + QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value); + QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const; + QPID_COMMON_INLINE_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; } + + QPID_COMMON_EXTERN void setString(const std::string& name, const std::string& value); + QPID_COMMON_EXTERN void setInt(const std::string& name, const int value); + QPID_COMMON_EXTERN void setInt64(const std::string& name, const int64_t value); + QPID_COMMON_EXTERN void setTimestamp(const std::string& name, const uint64_t value); + QPID_COMMON_EXTERN void setUInt64(const std::string& name, const uint64_t value); + QPID_COMMON_EXTERN void setTable(const std::string& name, const FieldTable& value); + QPID_COMMON_EXTERN void setArray(const std::string& name, const Array& value); + QPID_COMMON_EXTERN void setFloat(const std::string& name, const float value); + QPID_COMMON_EXTERN void setDouble(const std::string& name, const double value); + //void setDecimal(string& name, xxx& value); + + QPID_COMMON_EXTERN int getAsInt(const std::string& name) const; + QPID_COMMON_EXTERN uint64_t getAsUInt64(const std::string& name) const; + QPID_COMMON_EXTERN int64_t getAsInt64(const std::string& name) const; + QPID_COMMON_EXTERN std::string getAsString(const std::string& name) const; + + QPID_COMMON_EXTERN bool getTable(const std::string& name, FieldTable& value) const; + QPID_COMMON_EXTERN bool getArray(const std::string& name, Array& value) const; + QPID_COMMON_EXTERN bool getFloat(const std::string& name, float& value) const; + QPID_COMMON_EXTERN bool getDouble(const std::string& name, double& value) const; + //bool getTimestamp(const std::string& name, uint64_t& value) const; + //bool getDecimal(string& name, xxx& value); + QPID_COMMON_EXTERN void erase(const std::string& name); + + + QPID_COMMON_EXTERN bool operator==(const FieldTable& other) const; + + // Map-like interface. + ValueMap::const_iterator begin() const { return values.begin(); } + ValueMap::const_iterator end() const { return values.end(); } + ValueMap::const_iterator find(const std::string& s) const { return values.find(s); } + + ValueMap::iterator begin() { return values.begin(); } + ValueMap::iterator end() { return values.end(); } + ValueMap::iterator find(const std::string& s) { return values.find(s); } + + QPID_COMMON_EXTERN std::pair <ValueMap::iterator, bool> insert(const ValueMap::value_type&); + QPID_COMMON_EXTERN ValueMap::iterator insert(ValueMap::iterator, const ValueMap::value_type&); + void clear() { values.clear(); } + + // ### Hack Alert + + ValueMap::iterator getValues() { return values.begin(); } + + private: + ValueMap values; + + QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream& out, const FieldTable& body); +}; + +//class FieldNotFoundException{}; +//class UnknownFieldName : public FieldNotFoundException{}; +//class IncorrectFieldType : public FieldNotFoundException{}; +} +} + + +#endif diff --git a/qpid/cpp/include/qpid/framing/FieldValue.h b/qpid/cpp/include/qpid/framing/FieldValue.h new file mode 100644 index 0000000000..458de62fdf --- /dev/null +++ b/qpid/cpp/include/qpid/framing/FieldValue.h @@ -0,0 +1,474 @@ +#ifndef _framing_FieldValue_h +#define _framing_FieldValue_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" +#include "qpid/framing/amqp_types.h" +#include "qpid/framing/Buffer.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/CommonImportExport.h" + +#include <iostream> +#include <memory> +#include <vector> + +#include <assert.h> + +namespace qpid { +namespace framing { + +/** + * Exception that is the base exception for all field table errors. + * + * \ingroup clientapi + */ +class QPID_COMMON_CLASS_EXTERN FieldValueException : public qpid::Exception {}; + +/** + * Exception thrown when we can't perform requested conversion + * + * \ingroup clientapi + */ +struct QPID_COMMON_CLASS_EXTERN InvalidConversionException : public FieldValueException { + InvalidConversionException() {} +}; + +class List; + +/** + * Value that can appear in an AMQP field table + * + * \ingroup clientapi + */ +class QPID_COMMON_CLASS_EXTERN FieldValue { + public: + /* + * Abstract type for content of different types + */ + class Data { + public: + virtual ~Data() {}; + virtual uint32_t encodedSize() const = 0; + virtual void encode(Buffer& buffer) = 0; + virtual void decode(Buffer& buffer) = 0; + virtual bool operator==(const Data&) const = 0; + + virtual bool convertsToInt() const { return false; } + virtual bool convertsToString() const { return false; } + virtual int64_t getInt() const { throw InvalidConversionException();} + virtual std::string getString() const { throw InvalidConversionException(); } + + virtual void print(std::ostream& out) const = 0; + }; + + FieldValue(): data(0) {}; + // Default assignment operator is fine + void setType(uint8_t type); + QPID_COMMON_EXTERN uint8_t getType() const; + Data& getData() { return *data; } + uint32_t encodedSize() const { return 1 + data->encodedSize(); }; + bool empty() const { return data.get() == 0; } + void encode(Buffer& buffer); + void decode(Buffer& buffer); + QPID_COMMON_EXTERN bool operator==(const FieldValue&) const; + QPID_COMMON_INLINE_EXTERN bool operator!=(const FieldValue& v) const { return !(*this == v); } + + QPID_COMMON_EXTERN void print(std::ostream& out) const; + + template <typename T> bool convertsTo() const { return false; } + template <typename T> T get() const { throw InvalidConversionException(); } + + template <class T, int W> T getIntegerValue() const; + template <class T> T getIntegerValue() const; + template <class T, int W> T getFloatingPointValue() const; + template <int W> void getFixedWidthValue(unsigned char*) const; + template <class T> bool get(T&) const; + + protected: + FieldValue(uint8_t t, Data* d): typeOctet(t), data(d) {} + + QPID_COMMON_EXTERN static uint8_t* convertIfRequired(uint8_t* const octets, int width); + + private: + uint8_t typeOctet; + std::auto_ptr<Data> data; + +}; + +template <> +inline bool FieldValue::convertsTo<int>() const { return data->convertsToInt(); } + +template <> +inline bool FieldValue::convertsTo<int64_t>() const { return data->convertsToInt(); } + +template <> +inline bool FieldValue::convertsTo<std::string>() const { return data->convertsToString(); } + +template <> +inline int FieldValue::get<int>() const { return static_cast<int>(data->getInt()); } + +template <> +inline int64_t FieldValue::get<int64_t>() const { return data->getInt(); } + +template <> +inline std::string FieldValue::get<std::string>() const { return data->getString(); } + +inline std::ostream& operator<<(std::ostream& out, const FieldValue& v) { + v.print(out); + return out; +} + +template <int width> +class FixedWidthValue : public FieldValue::Data { + uint8_t octets[width]; + + public: + FixedWidthValue() {} + FixedWidthValue(const uint8_t (&data)[width]) : octets(data) {} + FixedWidthValue(const uint8_t* const data) + { + for (int i = 0; i < width; i++) octets[i] = data[i]; + } + FixedWidthValue(uint64_t v) + { + for (int i = width; i > 1; --i) { + octets[i-1] = (uint8_t) (0xFF & v); v >>= 8; + } + octets[0] = (uint8_t) (0xFF & v); + } + uint32_t encodedSize() const { return width; } + void encode(Buffer& buffer) { buffer.putRawData(octets, width); } + void decode(Buffer& buffer) { buffer.getRawData(octets, width); } + bool operator==(const Data& d) const { + const FixedWidthValue<width>* rhs = dynamic_cast< const FixedWidthValue<width>* >(&d); + if (rhs == 0) return false; + else return std::equal(&octets[0], &octets[width], &rhs->octets[0]); + } + + bool convertsToInt() const { return true; } + int64_t getInt() const + { + int64_t v = 0; + for (int i = 0; i < width-1; ++i) { + v |= octets[i]; v <<= 8; + } + v |= octets[width-1]; + return v; + } + uint8_t* rawOctets() { return octets; } + uint8_t* rawOctets() const { return octets; } + + void print(std::ostream& o) const { o << "F" << width << ":"; }; +}; + +template <class T, int W> +inline T FieldValue::getIntegerValue() const +{ + FixedWidthValue<W>* const fwv = dynamic_cast< FixedWidthValue<W>* const>(data.get()); + if (fwv) { + uint8_t* octets = fwv->rawOctets(); + T v = 0; + for (int i = 0; i < W-1; ++i) { + v |= octets[i]; v <<= 8; + } + v |= octets[W-1]; + return v; + } else { + throw InvalidConversionException(); + } +} + +template <class T> +inline T FieldValue::getIntegerValue() const +{ + FixedWidthValue<1>* const fwv = dynamic_cast< FixedWidthValue<1>* const>(data.get()); + if (fwv) { + uint8_t* octets = fwv->rawOctets(); + return octets[0]; + } else { + throw InvalidConversionException(); + } +} + +template <class T, int W> +inline T FieldValue::getFloatingPointValue() const { + FixedWidthValue<W>* const fwv = dynamic_cast< FixedWidthValue<W>* const>(data.get()); + if (fwv) { + T value; + uint8_t* const octets = convertIfRequired(fwv->rawOctets(), W); + uint8_t* const target = reinterpret_cast<uint8_t*>(&value); + for (size_t i = 0; i < W; ++i) target[i] = octets[i]; + return value; + } else { + throw InvalidConversionException(); + } +} + +template <int W> void FieldValue::getFixedWidthValue(unsigned char* value) const +{ + FixedWidthValue<W>* const fwv = dynamic_cast< FixedWidthValue<W>* const>(data.get()); + if (fwv) { + for (size_t i = 0; i < W; ++i) value[i] = fwv->rawOctets()[i]; + } else { + throw InvalidConversionException(); + } +} + +template <> +inline float FieldValue::get<float>() const { + return getFloatingPointValue<float, 4>(); +} + +template <> +inline double FieldValue::get<double>() const { + return getFloatingPointValue<double, 8>(); +} + +template <> +class FixedWidthValue<0> : public FieldValue::Data { + public: + // Implicit default constructor is fine + uint32_t encodedSize() const { return 0; } + void encode(Buffer&) {}; + void decode(Buffer&) {}; + bool operator==(const Data& d) const { + const FixedWidthValue<0>* rhs = dynamic_cast< const FixedWidthValue<0>* >(&d); + return rhs != 0; + } + void print(std::ostream& o) const { o << "F0"; }; +}; + +template <int lenwidth> +class VariableWidthValue : public FieldValue::Data { + std::vector<uint8_t> octets; + + public: + VariableWidthValue() {} + VariableWidthValue(const std::vector<uint8_t>& data) : octets(data) {} + VariableWidthValue(const uint8_t* start, const uint8_t* end) : octets(start, end) {} + uint32_t encodedSize() const { return lenwidth + octets.size(); } + void encode(Buffer& buffer) { + buffer.putUInt<lenwidth>(octets.size()); + if (octets.size() > 0) + buffer.putRawData(&octets[0], octets.size()); + }; + void decode(Buffer& buffer) { + uint32_t len = buffer.getUInt<lenwidth>(); + octets.resize(len); + if (len > 0) + buffer.getRawData(&octets[0], len); + } + bool operator==(const Data& d) const { + const VariableWidthValue<lenwidth>* rhs = dynamic_cast< const VariableWidthValue<lenwidth>* >(&d); + if (rhs == 0) return false; + else return octets==rhs->octets; + } + + bool convertsToString() const { return true; } + std::string getString() const { return std::string(octets.begin(), octets.end()); } + + void print(std::ostream& o) const { o << "V" << lenwidth << ":" << octets.size() << ":"; }; +}; + +template <class T> +class EncodedValue : public FieldValue::Data { + T value; + public: + + EncodedValue() {} + EncodedValue(const T& v) : value(v) {} + + T& getValue() { return value; } + const T& getValue() const { return value; } + + uint32_t encodedSize() const { return value.encodedSize(); } + + void encode(Buffer& buffer) { + value.encode(buffer); + }; + void decode(Buffer& buffer) { + value.decode(buffer); + } + bool operator==(const Data& d) const { + const EncodedValue<T>* rhs = dynamic_cast< const EncodedValue<T>* >(&d); + if (rhs == 0) return false; + else return value==rhs->value; + } + + void print(std::ostream& o) const { o << "[" << value << "]"; }; +}; + +/** + * Accessor that can be used to get values of type FieldTable, Array + * and List. + */ +template <class T> +inline bool FieldValue::get(T& t) const +{ + const EncodedValue<T>* v = dynamic_cast< EncodedValue<T>* >(data.get()); + if (v != 0) { + t = v->getValue(); + return true; + } else { + try { + t = get<T>(); + return true; + } catch (const InvalidConversionException&) { + return false; + } + } +} + +class Str8Value : public FieldValue { + public: + QPID_COMMON_EXTERN Str8Value(const std::string& v); +}; + +class Str16Value : public FieldValue { + public: + QPID_COMMON_EXTERN Str16Value(const std::string& v); +}; + +class Var16Value : public FieldValue { + public: + QPID_COMMON_EXTERN Var16Value(const std::string& v, uint8_t code); +}; + +class Var32Value : public FieldValue { + public: + QPID_COMMON_EXTERN Var32Value(const std::string& v, uint8_t code); +}; + +class Struct32Value : public FieldValue { + public: + QPID_COMMON_EXTERN Struct32Value(const std::string& v); +}; + +class FloatValue : public FieldValue +{ + public: + QPID_COMMON_EXTERN FloatValue(float f); +}; +class DoubleValue : public FieldValue +{ + public: + QPID_COMMON_EXTERN DoubleValue(double f); +}; + +/* + * Basic integer value encodes as signed 32 bit + */ +class IntegerValue : public FieldValue { + public: + QPID_COMMON_EXTERN IntegerValue(int v); +}; + +class TimeValue : public FieldValue { + public: + QPID_COMMON_EXTERN TimeValue(uint64_t v); +}; + +class Integer64Value : public FieldValue { + public: + QPID_COMMON_EXTERN Integer64Value(int64_t v); +}; + +class Unsigned64Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned64Value(uint64_t v); +}; + +class FieldTableValue : public FieldValue { + public: + typedef FieldTable ValueType; + QPID_COMMON_EXTERN FieldTableValue(const FieldTable&); +}; + +class ArrayValue : public FieldValue { + public: + QPID_COMMON_EXTERN ArrayValue(const Array&); +}; + +class VoidValue : public FieldValue { + public: + QPID_COMMON_EXTERN VoidValue(); +}; + +class BoolValue : public FieldValue { + public: + QPID_COMMON_EXTERN BoolValue(bool); +}; + +class Unsigned8Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned8Value(uint8_t); +}; + +class Unsigned16Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned16Value(uint16_t); +}; + +class Unsigned32Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned32Value(uint32_t); +}; + +class Integer8Value : public FieldValue { + public: + QPID_COMMON_EXTERN Integer8Value(int8_t); +}; + +class Integer16Value : public FieldValue { + public: + QPID_COMMON_EXTERN Integer16Value(int16_t); +}; + +typedef IntegerValue Integer32Value; + +class ListValue : public FieldValue { + public: + typedef List ValueType; + QPID_COMMON_EXTERN ListValue(const List&); +}; + +class UuidValue : public FieldValue { + public: + QPID_COMMON_EXTERN UuidValue(const unsigned char*); +}; + +template <class T> +bool getEncodedValue(FieldTable::ValuePtr vptr, T& value) +{ + if (vptr) { + const EncodedValue<T>* ev = dynamic_cast< EncodedValue<T>* >(&(vptr->getData())); + if (ev != 0) { + value = ev->getValue(); + return true; + } + } + return false; +} + +}} // qpid::framing + +#endif diff --git a/qpid/cpp/include/qpid/framing/List.h b/qpid/cpp/include/qpid/framing/List.h new file mode 100644 index 0000000000..417fd4bffb --- /dev/null +++ b/qpid/cpp/include/qpid/framing/List.h @@ -0,0 +1,77 @@ +#ifndef QPID_FRAMING_LIST_H +#define QPID_FRAMING_LIST_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/CommonImportExport.h" +#include "qpid/framing/amqp_types.h" +#include <iostream> +#include <list> +#include <boost/shared_ptr.hpp> + +namespace qpid { +namespace framing { + +class Buffer; +class FieldValue; + +/** + * Representation of an AMQP 0-10 list + */ +class QPID_COMMON_CLASS_EXTERN List +{ + public: + typedef boost::shared_ptr<FieldValue> ValuePtr; + typedef std::list<ValuePtr> Values; + typedef Values::const_iterator const_iterator; + typedef Values::iterator iterator; + typedef Values::const_reference const_reference; + typedef Values::reference reference; + + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer); + + QPID_COMMON_EXTERN bool operator==(const List& other) const; + + // std collection interface. + QPID_COMMON_INLINE_EXTERN const_iterator begin() const { return values.begin(); } + QPID_COMMON_INLINE_EXTERN const_iterator end() const { return values.end(); } + QPID_COMMON_INLINE_EXTERN iterator begin() { return values.begin(); } + QPID_COMMON_INLINE_EXTERN iterator end(){ return values.end(); } + + QPID_COMMON_INLINE_EXTERN ValuePtr front() const { return values.front(); } + QPID_COMMON_INLINE_EXTERN ValuePtr back() const { return values.back(); } + QPID_COMMON_INLINE_EXTERN size_t size() const { return values.size(); } + + QPID_COMMON_INLINE_EXTERN iterator insert(iterator i, ValuePtr value) { return values.insert(i, value); } + QPID_COMMON_INLINE_EXTERN void erase(iterator i) { values.erase(i); } + QPID_COMMON_INLINE_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); } + QPID_COMMON_INLINE_EXTERN void pop_back() { values.pop_back(); } + + private: + Values values; + + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const List& list); +}; +}} // namespace qpid::framing + +#endif /*!QPID_FRAMING_LIST_H*/ diff --git a/qpid/cpp/include/qpid/framing/ProtocolVersion.h b/qpid/cpp/include/qpid/framing/ProtocolVersion.h new file mode 100644 index 0000000000..30094c165d --- /dev/null +++ b/qpid/cpp/include/qpid/framing/ProtocolVersion.h @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _ProtocolVersion_ +#define _ProtocolVersion_ + +#include "qpid/framing/amqp_types.h" +#include "qpid/CommonImportExport.h" + +namespace qpid +{ +namespace framing +{ + +class QPID_COMMON_CLASS_EXTERN ProtocolVersion +{ +private: + uint8_t major_; + uint8_t minor_; + +public: + explicit ProtocolVersion(uint8_t _major=0, uint8_t _minor=0) + : major_(_major), minor_(_minor) {} + + QPID_COMMON_INLINE_EXTERN uint8_t getMajor() const { return major_; } + QPID_COMMON_INLINE_EXTERN void setMajor(uint8_t major) { major_ = major; } + QPID_COMMON_INLINE_EXTERN uint8_t getMinor() const { return minor_; } + QPID_COMMON_INLINE_EXTERN void setMinor(uint8_t minor) { minor_ = minor; } + QPID_COMMON_EXTERN const std::string toString() const; + + QPID_COMMON_EXTERN ProtocolVersion& operator=(ProtocolVersion p); + + QPID_COMMON_EXTERN bool operator==(ProtocolVersion p) const; + QPID_COMMON_INLINE_EXTERN bool operator!=(ProtocolVersion p) const { return ! (*this == p); } +}; + +} // namespace framing +} // namespace qpid + + +#endif // ifndef _ProtocolVersion_ diff --git a/qpid/cpp/include/qpid/framing/SequenceNumber.h b/qpid/cpp/include/qpid/framing/SequenceNumber.h new file mode 100644 index 0000000000..eed15a4b75 --- /dev/null +++ b/qpid/cpp/include/qpid/framing/SequenceNumber.h @@ -0,0 +1,79 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _framing_SequenceNumber_h +#define _framing_SequenceNumber_h + +#include "qpid/framing/amqp_types.h" +#include <boost/operators.hpp> +#include <iosfwd> +#include "qpid/CommonImportExport.h" + +namespace qpid { +namespace framing { + +class Buffer; + +/** + * 4-byte sequence number that 'wraps around'. + */ +class QPID_COMMON_CLASS_EXTERN SequenceNumber : public +boost::equality_comparable< + SequenceNumber, boost::less_than_comparable< + SequenceNumber, boost::incrementable< + SequenceNumber, boost::decrementable<SequenceNumber> > > > +{ + int32_t value; + + public: + SequenceNumber(uint32_t v=0) : value(v) {} + + SequenceNumber& operator++() { ++value; return *this; } + SequenceNumber& operator--() { --value; return *this; } + bool operator==(const SequenceNumber& other) const { return value == other.value; } + bool operator<(const SequenceNumber& other) const { return (value - other.value) < 0; } + uint32_t getValue() const { return uint32_t(value); } + operator uint32_t() const { return uint32_t(value); } + + void encode(Buffer& buffer) const; + void decode(Buffer& buffer); + uint32_t encodedSize() const; + + template <class S> void serialize(S& s) { s(value); } + + friend inline int32_t operator-(const SequenceNumber& a, const SequenceNumber& b); +}; + +inline int32_t operator-(const SequenceNumber& a, const SequenceNumber& b) { + return int32_t(a.value - b.value); +} + +struct Window +{ + SequenceNumber hwm; + SequenceNumber lwm; +}; + +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const SequenceNumber& n); + +}} // namespace qpid::framing + + +#endif diff --git a/qpid/cpp/include/qpid/framing/SequenceSet.h b/qpid/cpp/include/qpid/framing/SequenceSet.h new file mode 100644 index 0000000000..0a78e418ba --- /dev/null +++ b/qpid/cpp/include/qpid/framing/SequenceSet.h @@ -0,0 +1,69 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#ifndef _framing_SequenceSet_h +#define _framing_SequenceSet_h + +#include "qpid/framing/SequenceNumber.h" +#include "qpid/RangeSet.h" +#include "qpid/CommonImportExport.h" + +namespace qpid { +namespace framing { +class Buffer; + +class QPID_COMMON_CLASS_EXTERN SequenceSet : public RangeSet<SequenceNumber> { + public: + SequenceSet() {} + SequenceSet(const RangeSet<SequenceNumber>& r) + : RangeSet<SequenceNumber>(r) {} + SequenceSet(const SequenceNumber& s) { add(s); } + SequenceSet(const SequenceNumber& start, const SequenceNumber finish) { add(start,finish); } + + + void encode(Buffer& buffer) const; + void decode(Buffer& buffer); + uint32_t encodedSize() const; + + QPID_COMMON_EXTERN bool contains(const SequenceNumber& s) const; + QPID_COMMON_EXTERN void add(const SequenceNumber& s); + QPID_COMMON_EXTERN void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range + QPID_COMMON_EXTERN void add(const SequenceSet& set); + QPID_COMMON_EXTERN void remove(const SequenceNumber& s); + QPID_COMMON_EXTERN void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range + QPID_COMMON_EXTERN void remove(const SequenceSet& set); + + template <class T> void for_each(T& t) const { + for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++) + t(i->first(), i->last()); + } + + template <class T> void for_each(const T& t) const { + for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++) + t(i->first(), i->last()); + } + + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceSet&); +}; + +}} // namespace qpid::framing + + +#endif diff --git a/qpid/cpp/include/qpid/framing/StructHelper.h b/qpid/cpp/include/qpid/framing/StructHelper.h new file mode 100644 index 0000000000..21f9b91fa9 --- /dev/null +++ b/qpid/cpp/include/qpid/framing/StructHelper.h @@ -0,0 +1,57 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 _StructHelper_ +#define _StructHelper_ + +#include "qpid/Exception.h" +#include "qpid/CommonImportExport.h" +#include "qpid/framing/Buffer.h" + +#include <stdlib.h> // For alloca + +namespace qpid { +namespace framing { + +class QPID_COMMON_CLASS_EXTERN StructHelper +{ +public: + + template <class T> void encode(const T t, std::string& data) { + uint32_t size = t.bodySize() + 2/*type*/; + data.resize(size); + Buffer wbuffer(const_cast<char*>(data.data()), size); + wbuffer.putShort(T::TYPE); + t.encodeStructBody(wbuffer); + } + + template <class T> void decode(T& t, const std::string& data) { + Buffer rbuffer(const_cast<char*>(data.data()), data.length()); + uint16_t type = rbuffer.getShort(); + if (type == T::TYPE) { + t.decodeStructBody(rbuffer); + } else { + throw Exception("Type code does not match"); + } + } +}; + +}} +#endif diff --git a/qpid/cpp/include/qpid/framing/Uuid.h b/qpid/cpp/include/qpid/framing/Uuid.h new file mode 100644 index 0000000000..ccfd7e9534 --- /dev/null +++ b/qpid/cpp/include/qpid/framing/Uuid.h @@ -0,0 +1,91 @@ +#ifndef QPID_FRAMING_UUID_H +#define QPID_FRAMING_UUID_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/CommonImportExport.h" +#include "qpid/sys/IntegerTypes.h" + +#include <boost/array.hpp> + +#include <ostream> +#include <istream> + +namespace qpid { +namespace framing { + +class Buffer; + +/** + * A UUID is represented as a boost::array of 16 bytes. + * + * Full value semantics, operators ==, < etc. are provided by + * boost::array so Uuid can be the key type in a map etc. + * + * TODO: change this implementation as it leaks boost into the + * client API + */ +struct Uuid : public boost::array<uint8_t, 16> { + /** If unique is true, generate a unique ID else a null ID. */ + QPID_COMMON_EXTERN Uuid(bool unique=false); + + /** Copy from 16 bytes of data. */ + QPID_COMMON_EXTERN Uuid(const uint8_t* data); + + // Default op= and copy ctor are fine. + // boost::array gives us ==, < etc. + + /** Copy from 16 bytes of data. */ + QPID_COMMON_EXTERN void assign(const uint8_t* data); + + /** Set to a new unique identifier. */ + QPID_COMMON_EXTERN void generate(); + + /** Set to all zeros. */ + QPID_COMMON_EXTERN void clear(); + + /** Test for null (all zeros). */ + QPID_COMMON_EXTERN bool isNull() const; + QPID_COMMON_INLINE_EXTERN operator bool() const { return !isNull(); } + QPID_COMMON_INLINE_EXTERN bool operator!() const { return isNull(); } + + QPID_COMMON_EXTERN void encode(framing::Buffer& buf) const; + QPID_COMMON_EXTERN void decode(framing::Buffer& buf); + QPID_COMMON_INLINE_EXTERN uint32_t encodedSize() const + { return static_cast<uint32_t>(size()); } + + /** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ + QPID_COMMON_EXTERN std::string str() const; + + template <class S> void serialize(S& s) { + s.raw(begin(), size()); + } +}; + +/** Print in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ +QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, Uuid); + +/** Read from format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ +QPID_COMMON_EXTERN std::istream& operator>>(std::istream&, Uuid&); + +}} // namespace qpid::framing + + + +#endif /*!QPID_FRAMING_UUID_H*/ diff --git a/qpid/cpp/include/qpid/framing/amqp_types.h b/qpid/cpp/include/qpid/framing/amqp_types.h new file mode 100644 index 0000000000..d9088b7a12 --- /dev/null +++ b/qpid/cpp/include/qpid/framing/amqp_types.h @@ -0,0 +1,66 @@ +#ifndef AMQP_TYPES_H +#define AMQP_TYPES_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. + * + */ + +/** \file + * Definitions and forward declarations of all types used + * in AMQP messages. + */ + +#include "qpid/sys/IntegerTypes.h" +#include <string> + +namespace qpid { +namespace framing { + +using std::string; +typedef uint8_t FrameType; +typedef uint16_t ChannelId; +typedef uint32_t BatchOffset; +typedef uint8_t ClassId; +typedef uint8_t MethodId; +typedef uint16_t ReplyCode; + +// Types represented by classes. +class Content; +class FieldTable; +class SequenceNumberSet; +struct Uuid; + +// Useful constants + +/** Maximum channel ID used by broker. Reserve high bit for internal use.*/ +const ChannelId CHANNEL_MAX=(ChannelId(~1))>>1; +const ChannelId CHANNEL_HIGH_BIT= ChannelId(~CHANNEL_MAX); + +// Forward declare class types +class FramingContent; +class FieldTable; +class SequenceNumberSet; +class SequenceSet; +struct Uuid; + +// Enum types +enum DeliveryMode { TRANSIENT = 1, PERSISTENT = 2}; + +}} // namespace qpid::framing +#endif diff --git a/qpid/cpp/include/qpid/framing/amqp_types_full.h b/qpid/cpp/include/qpid/framing/amqp_types_full.h new file mode 100644 index 0000000000..c5d84dedea --- /dev/null +++ b/qpid/cpp/include/qpid/framing/amqp_types_full.h @@ -0,0 +1,38 @@ +#ifndef _framing_amqp_types_decl_h +#define _framing_amqp_types_decl_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. + * + */ + +/** \file + * Definitions and full declarations of all types used + * in AMQP messages. + * + * It's better to include amqp_types.h in another header instead of this file + * unless the header actually needs the full declarations. Including + * full declarations when forward declarations would increase compile + * times. + */ + +#include "qpid/framing/amqp_types.h" +#include "qpid/framing/Array.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/SequenceSet.h" +#include "qpid/framing/Uuid.h" + +#endif /*!_framing_amqp_types_decl_h*/ diff --git a/qpid/cpp/include/qpid/log/Logger.h b/qpid/cpp/include/qpid/log/Logger.h new file mode 100644 index 0000000000..d255b7e150 --- /dev/null +++ b/qpid/cpp/include/qpid/log/Logger.h @@ -0,0 +1,117 @@ +#ifndef QPID_LOG_LOGGER_H +#define QPID_LOG_LOGGER_H + +/* + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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/Selector.h" +#include "qpid/log/Options.h" +#include "qpid/sys/Mutex.h" +#include <boost/ptr_container/ptr_vector.hpp> +#include <boost/noncopyable.hpp> +#include <set> +#include "qpid/CommonImportExport.h" + +namespace qpid { +namespace log { + +/** + * Central logging agent. + * + * Thread safe, singleton. + * + * The Logger provides all needed functionality for selecting and + * formatting logging output. The actual outputting of log records + * is handled by Logger::Output-derived classes instantiated by the + * platform's sink-related options. + */ +class QPID_COMMON_CLASS_EXTERN Logger : private boost::noncopyable { + public: + /** Flags indicating what to include in the log output */ + enum FormatFlag { FILE=1, LINE=2, FUNCTION=4, LEVEL=8, TIME=16, THREAD=32, HIRES=64}; + + /** + * Logging output sink. + * + * The Output sink provides an interface to direct logging output to. + * Logging sinks are primarily platform-specific as provided for on + * each platform. + * + * Implementations of Output must be thread safe. + */ + class Output { + public: + QPID_COMMON_EXTERN Output(); + QPID_COMMON_EXTERN virtual ~Output(); + /** Receives the statemnt of origin and formatted message to log. */ + virtual void log(const Statement&, const std::string&) =0; + }; + + QPID_COMMON_EXTERN static Logger& instance(); + + QPID_COMMON_EXTERN Logger(); + QPID_COMMON_EXTERN ~Logger(); + + /** Select the messages to be logged. */ + QPID_COMMON_EXTERN void select(const Selector& s); + + /** Set the formatting flags, bitwise OR of FormatFlag values. */ + QPID_COMMON_EXTERN void format(int formatFlags); + + /** Set format flags from options object. + *@returns computed flags. + */ + QPID_COMMON_EXTERN int format(const Options&); + + /** Configure logger from Options */ + QPID_COMMON_EXTERN void configure(const Options& o); + + /** Reset the log selectors */ + QPID_COMMON_EXTERN void reconfigure(const std::vector<std::string>& selectors); + + /** Add a statement. */ + QPID_COMMON_EXTERN void add(Statement& s); + + /** Log a message. */ + QPID_COMMON_EXTERN void log(const Statement&, const std::string&); + + /** Add an output destination for messages */ + QPID_COMMON_EXTERN void output(std::auto_ptr<Output> out); + + /** Set a prefix for all messages */ + QPID_COMMON_EXTERN void setPrefix(const std::string& prefix); + + /** Reset the logger. */ + QPID_COMMON_EXTERN void clear(); + + /** Get the options used to configure the logger. */ + QPID_COMMON_INLINE_EXTERN const Options& getOptions() const { return options; } + + + private: + typedef boost::ptr_vector<Output> Outputs; + typedef std::set<Statement*> Statements; + + sys::Mutex lock; + inline void enable_unlocked(Statement* s); + + Statements statements; + Outputs outputs; + Selector selector; + int flags; + std::string prefix; + Options options; +}; + +}} // namespace qpid::log + + +#endif /*!QPID_LOG_LOGGER_H*/ diff --git a/qpid/cpp/include/qpid/log/Options.h b/qpid/cpp/include/qpid/log/Options.h new file mode 100644 index 0000000000..17cbfde9bc --- /dev/null +++ b/qpid/cpp/include/qpid/log/Options.h @@ -0,0 +1,50 @@ +#ifndef QPID_LOG_OPTIONS_H +#define QPID_LOG_OPTIONS_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/Options.h" +#include "qpid/CommonImportExport.h" +#include "qpid/log/SinkOptions.h" +#include <iosfwd> +#include <memory> + +namespace qpid { +namespace log { + +/** Logging options for config parser. */ +struct Options : public qpid::Options { + /** Pass argv[0] for use in syslog output */ + QPID_COMMON_EXTERN Options(const std::string& argv0_=std::string(), + const std::string& name_="Logging options"); + QPID_COMMON_EXTERN Options(const Options &); + + QPID_COMMON_EXTERN Options& operator=(const Options&); + + std::string argv0; + std::string name; + std::vector<std::string> selectors; + bool time, level, thread, source, function, hiresTs; + bool trace; + std::string prefix; + std::auto_ptr<SinkOptions> sinkOptions; +}; + +}} // namespace qpid::log + +#endif /*!QPID_LOG_OPTIONS_H*/ diff --git a/qpid/cpp/include/qpid/log/Selector.h b/qpid/cpp/include/qpid/log/Selector.h new file mode 100644 index 0000000000..061152d7e2 --- /dev/null +++ b/qpid/cpp/include/qpid/log/Selector.h @@ -0,0 +1,71 @@ +#ifndef SELECTOR_H +#define SELECTOR_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/log/Statement.h" +#include "qpid/CommonImportExport.h" +#include <vector> + +namespace qpid { +namespace log { +struct Options; + +/** + * A selector identifies the set of log messages to enable. + * + * Thread object unsafe, pass-by-value type. + */ +class Selector { + public: + /** Empty selector selects nothing */ + Selector() {} + + /** Set selector from Options */ + QPID_COMMON_EXTERN Selector(const Options&); + + /** Equavlient to: Selector s; s.enable(l, s) */ + Selector(Level l, const std::string& s=std::string()) { + enable(l,s); + } + + Selector(const std::string& enableStr) { enable(enableStr); } + /** + * Enable messages with level in levels where the file + * name contains substring. Empty string matches all. + */ + void enable(Level level, const std::string& substring=std::string()) { + substrings[level].push_back(substring); + } + + /** Enable based on a 'level[+]:file' string */ + QPID_COMMON_EXTERN void enable(const std::string& enableStr); + + /** True if level is enabled for file. */ + QPID_COMMON_EXTERN bool isEnabled(Level level, const char* function); + + private: + std::vector<std::string> substrings[LevelTraits::COUNT]; +}; + + +}} // namespace qpid::log + + +#endif /*!SELECTOR_H*/ diff --git a/qpid/cpp/include/qpid/log/SinkOptions.h b/qpid/cpp/include/qpid/log/SinkOptions.h new file mode 100644 index 0000000000..7ec2cfbc17 --- /dev/null +++ b/qpid/cpp/include/qpid/log/SinkOptions.h @@ -0,0 +1,64 @@ +#ifndef QPID_LOG_SINKOPTIONS_H +#define QPID_LOG_SINKOPTIONS_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/Options.h" +#include <string> + +namespace qpid { +namespace log { + +class Logger; + +/** + * Logging sink options. + * + * Most logging sink options will be platform-specific, even if some are + * duplicated. The range of platforms to which this code may be ported + * can't be assumed to all have C++ iostreams or files. Thus, this class + * is primarily for implementing in a platform-specific way. + */ +struct SinkOptions : public qpid::Options { + + // Create a platform's SinkOptions. Pass argv0 as the program name, + // useful for syslog-type logging. + static SinkOptions *create(const std::string& argv0=std::string()); + + SinkOptions(const std::string& name="Logging sink options") + : qpid::Options(name) + {} + virtual ~SinkOptions() {} + + virtual SinkOptions& operator=(const SinkOptions&) = 0; + + // This allows the caller to indicate that there's no normal outputs + // available. For example, when running as a daemon. In these cases, the + // platform's "syslog"-type output should replace the default stderr + // unless some other sink has been selected. + virtual void detached(void) = 0; + + // The Logger acting on these options calls setup() to request any + // Sinks be set up and fed back to the logger. + virtual void setup(Logger *logger) = 0; +}; + +}} // namespace qpid::log + +#endif /*!QPID_LOG_OPTIONS_H*/ diff --git a/qpid/cpp/include/qpid/log/Statement.h b/qpid/cpp/include/qpid/log/Statement.h new file mode 100644 index 0000000000..7b3ab60b81 --- /dev/null +++ b/qpid/cpp/include/qpid/log/Statement.h @@ -0,0 +1,139 @@ +#ifndef STATEMENT_H +#define STATEMENT_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/Msg.h" +#include "qpid/CommonImportExport.h" +#include <boost/current_function.hpp> + +namespace qpid { +namespace log { + +/** Debugging severity levels + * - trace: High-volume debugging messages. + * - debug: Debugging messages. + * - info: Informational messages. + * - notice: Normal but significant condition. + * - warning: Warn of a possible problem. + * - error: A definite error has occured. + * - critical: System in danger of severe failure. + */ +enum Level { trace, debug, info, notice, warning, error, critical }; +struct LevelTraits { + static const int COUNT=critical+1; + + /** Get level from string name. + *@exception if name invalid. + */ + static Level level(const char* name); + + /** Get level from string name. + *@exception if name invalid. + */ + static Level level(const std::string& name) { + return level(name.c_str()); + } + + /** String name of level */ + static const char* name(Level); +}; + +/** POD struct representing a logging statement in source code. */ +struct Statement { + bool enabled; + const char* file; + int line; + const char* function; + Level level; + + QPID_COMMON_EXTERN void log(const std::string& message); + + struct Initializer { + QPID_COMMON_EXTERN Initializer(Statement& s); + Statement& statement; + }; +}; + +///@internal static initializer for a Statement. +#define QPID_LOG_STATEMENT_INIT(level) \ + { 0, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, (::qpid::log::level) } + +/** + * Like QPID_LOG but computes an additional boolean test expression + * to determine if the message should be logged. Evaluation of both + * the test and message expressions occurs only if the requested log level + * is enabled. + *@param LEVEL severity Level for message, should be one of: + * debug, info, notice, warning, error, critical. NB no qpid::log:: prefix. + *@param TEST message is logged only if expression TEST evaluates to true. + *@param MESSAGE any object with an @eostream operator<<, or a sequence + * like of ostreamable objects separated by @e<<. + */ +#define QPID_LOG_IF(LEVEL, TEST, MESSAGE) \ + do { \ + using ::qpid::log::Statement; \ + static Statement stmt_= QPID_LOG_STATEMENT_INIT(LEVEL); \ + static Statement::Initializer init_(stmt_); \ + if (stmt_.enabled && (TEST)) \ + stmt_.log(::qpid::Msg() << MESSAGE); \ + } while(0) + +/** + * FLAG must be a boolean variable. Assigns FLAG to true iff logging + * is enabled for LEVEL in the calling context. Use when extra + * support code is needed to generate log messages, to ensure that it + * is only run if the logging level is enabled. + * e.g. + * bool logWarning; + * QPID_LOG_TEST(LEVEL, logWarning); + * if (logWarning) { do stuff needed for warning log messages } + */ +#define QPID_LOG_TEST(LEVEL, FLAG) \ + do { \ + using ::qpid::log::Statement; \ + static Statement stmt_= QPID_LOG_STATEMENT_INIT(LEVEL); \ + static Statement::Initializer init_(stmt_); \ + FLAG = stmt_.enabled; \ + } while(0) + +/** + * Macro for log statements. Example of use: + * @code + * QPID_LOG(debug, "There are " << foocount << " foos in the bar."); + * QPID_LOG(error, boost::format("Dohickey %s exploded") % dohicky.name()); + * @endcode + * + * You can subscribe to log messages by level, by component, by filename + * or a combination @see Configuration. + + *@param LEVEL severity Level for message, should be one of: + * debug, info, notice, warning, error, critical. NB no qpid::log:: prefix. + *@param MESSAGE any object with an @eostream operator<<, or a sequence + * like of ostreamable objects separated by @e<<. + */ +#define QPID_LOG(LEVEL, MESSAGE) QPID_LOG_IF(LEVEL, true, MESSAGE); + +}} // namespace qpid::log + + + + +#endif /*!STATEMENT_H*/ + diff --git a/qpid/cpp/include/qpid/management/Args.h b/qpid/cpp/include/qpid/management/Args.h new file mode 100644 index 0000000000..5d1cb7e01d --- /dev/null +++ b/qpid/cpp/include/qpid/management/Args.h @@ -0,0 +1,44 @@ +#ifndef _Args_ +#define _Args_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT 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 management { + +class Args +{ + public: + + virtual ~Args (void) = 0; + +}; + +inline Args::~Args (void) {} + +class ArgsNone : public Args +{ +}; + +}} + + +#endif /*!_Args_*/ diff --git a/qpid/cpp/include/qpid/management/Buffer.h b/qpid/cpp/include/qpid/management/Buffer.h new file mode 100644 index 0000000000..c32494b8c0 --- /dev/null +++ b/qpid/cpp/include/qpid/management/Buffer.h @@ -0,0 +1,106 @@ +#ifndef _Management_Buffer_ +#define _Management_Buffer_ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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/CommonImportExport.h" +#include "qpid/types/Exception.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qpid { +namespace framing { + class Buffer; +} + +namespace management { + +struct OutOfBounds : qpid::types::Exception { + OutOfBounds() : qpid::types::Exception(std::string("Out of Bounds")) {} +}; + + +/** + * This class is a wrapper around qpid::framing::Buffer that does not include any dependencies + * from boost or from qpid::framing. + */ +class Buffer +{ +public: + QPID_COMMON_EXTERN Buffer(char* data=0, uint32_t size=0); + QPID_COMMON_EXTERN ~Buffer(); + + QPID_COMMON_EXTERN void record(); + QPID_COMMON_EXTERN void restore(bool reRecord = false); + QPID_COMMON_EXTERN void reset(); + + QPID_COMMON_EXTERN uint32_t available(); + QPID_COMMON_EXTERN uint32_t getSize(); + QPID_COMMON_EXTERN uint32_t getPosition(); + QPID_COMMON_EXTERN char* getPointer(); + + QPID_COMMON_EXTERN void putOctet(uint8_t i); + QPID_COMMON_EXTERN void putShort(uint16_t i); + QPID_COMMON_EXTERN void putLong(uint32_t i); + QPID_COMMON_EXTERN void putLongLong(uint64_t i); + QPID_COMMON_EXTERN void putInt8(int8_t i); + QPID_COMMON_EXTERN void putInt16(int16_t i); + QPID_COMMON_EXTERN void putInt32(int32_t i); + QPID_COMMON_EXTERN void putInt64(int64_t i); + QPID_COMMON_EXTERN void putFloat(float f); + QPID_COMMON_EXTERN void putDouble(double f); + QPID_COMMON_EXTERN void putBin128(const uint8_t* b); + + QPID_COMMON_EXTERN uint8_t getOctet(); + QPID_COMMON_EXTERN uint16_t getShort(); + QPID_COMMON_EXTERN uint32_t getLong(); + QPID_COMMON_EXTERN uint64_t getLongLong(); + QPID_COMMON_EXTERN int8_t getInt8(); + QPID_COMMON_EXTERN int16_t getInt16(); + QPID_COMMON_EXTERN int32_t getInt32(); + QPID_COMMON_EXTERN int64_t getInt64(); + QPID_COMMON_EXTERN float getFloat(); + QPID_COMMON_EXTERN double getDouble(); + + QPID_COMMON_EXTERN void putShortString(const std::string& s); + QPID_COMMON_EXTERN void putMediumString(const std::string& s); + QPID_COMMON_EXTERN void putLongString(const std::string& s); + QPID_COMMON_EXTERN void getShortString(std::string& s); + QPID_COMMON_EXTERN void getMediumString(std::string& s); + QPID_COMMON_EXTERN void getLongString(std::string& s); + QPID_COMMON_EXTERN void getBin128(uint8_t* b); + + QPID_COMMON_EXTERN void putMap(const types::Variant::Map& map); + QPID_COMMON_EXTERN void putList(const types::Variant::List& list); + QPID_COMMON_EXTERN void getMap(types::Variant::Map& map); + QPID_COMMON_EXTERN void getList(types::Variant::List& list); + + QPID_COMMON_EXTERN void putRawData(const std::string& s); + QPID_COMMON_EXTERN void getRawData(std::string& s, uint32_t size); + + QPID_COMMON_EXTERN void putRawData(const uint8_t* data, size_t size); + QPID_COMMON_EXTERN void getRawData(uint8_t* data, size_t size); + +private: + framing::Buffer* impl; +}; + +}} // namespace qpid::management + +#endif diff --git a/qpid/cpp/include/qpid/management/ConnectionSettings.h b/qpid/cpp/include/qpid/management/ConnectionSettings.h new file mode 100644 index 0000000000..b631ffa658 --- /dev/null +++ b/qpid/cpp/include/qpid/management/ConnectionSettings.h @@ -0,0 +1,118 @@ +#ifndef _management_ConnectionSettings_h +#define _management_ConnectionSettings_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/CommonImportExport.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qpid { +namespace management { + +/** + * Settings for a Connection. + */ +struct ConnectionSettings { + + QPID_COMMON_EXTERN ConnectionSettings(); + QPID_COMMON_EXTERN virtual ~ConnectionSettings(); + + /** + * The protocol used for the connection (defaults to 'tcp') + */ + std::string protocol; + + /** + * The host (or ip address) to connect to (defaults to 'localhost'). + */ + std::string host; + /** + * The port to connect to (defaults to 5672). + */ + uint16_t port; + /** + * Allows an AMQP 'virtual host' to be specified for the + * connection. + */ + std::string virtualhost; + + /** + * The username to use when authenticating the connection. If not + * specified the current users login is used if available. + */ + std::string username; + /** + * The password to use when authenticating the connection. + */ + std::string password; + /** + * The SASL mechanism to use when authenticating the connection; + * the options are currently PLAIN or ANONYMOUS. + */ + std::string mechanism; + /** + * Allows a locale to be specified for the connection. + */ + std::string locale; + /** + * Allows a heartbeat frequency to be specified + */ + uint16_t heartbeat; + /** + * The maximum number of channels that the client will request for + * use on this connection. + */ + uint16_t maxChannels; + /** + * The maximum frame size that the client will request for this + * connection. + */ + uint16_t maxFrameSize; + /** + * Limit the size of the connections send buffer . The buffer + * is limited to bounds * maxFrameSize. + */ + unsigned int bounds; + /** + * If true, TCP_NODELAY will be set for the connection. + */ + bool tcpNoDelay; + /** + * SASL service name + */ + std::string service; + /** + * Minimum acceptable strength of any SASL negotiated security + * layer. 0 means no security layer required. + */ + unsigned int minSsf; + /** + * Maximum acceptable strength of any SASL negotiated security + * layer. 0 means no security layer allowed. + */ + unsigned int maxSsf; +}; + +}} + +#endif + diff --git a/qpid/cpp/include/qpid/management/Manageable.h b/qpid/cpp/include/qpid/management/Manageable.h new file mode 100644 index 0000000000..1e5cd8bc42 --- /dev/null +++ b/qpid/cpp/include/qpid/management/Manageable.h @@ -0,0 +1,77 @@ +#ifndef _Manageable_ +#define _Manageable_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT 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/ManagementObject.h" +#include "qpid/management/Args.h" +#include <string> +#include "qpid/CommonImportExport.h" + +namespace qpid { +namespace management { + +class QPID_COMMON_EXTERN Manageable +{ + public: + + virtual ~Manageable(void) = 0; + + // status_t is a type used to pass completion status from the method handler. + // + typedef uint32_t status_t; + static std::string StatusText(status_t status, std::string text = std::string()); + + static const status_t STATUS_OK = 0; + static const status_t STATUS_UNKNOWN_OBJECT = 1; + static const status_t STATUS_UNKNOWN_METHOD = 2; + static const status_t STATUS_NOT_IMPLEMENTED = 3; + static const status_t STATUS_PARAMETER_INVALID = 4; + static const status_t STATUS_FEATURE_NOT_IMPLEMENTED = 5; + static const status_t STATUS_FORBIDDEN = 6; + static const status_t STATUS_EXCEPTION = 7; + static const status_t STATUS_USER = 0x00010000; + + // Every "Manageable" object must hold a reference to exactly one + // management object. This object is always of a class derived from + // the pure-virtual "ManagementObject". + // + // This accessor function returns a pointer to the management object. + // + virtual ManagementObject* GetManagementObject(void) const = 0; + + // Every "Manageable" object must implement ManagementMethod. This + // function is called when a remote management client invokes a method + // on this object. The input and output arguments are specific to the + // method being called and must be down-cast to the appropriate sub class + // before use. + virtual status_t ManagementMethod(uint32_t methodId, Args& args, std::string& text); + + // This optional method can be overridden to allow the agent application to + // authorize method invocations. Return true iff the authenticated user identified + // in userId us authorized to execute the method. + virtual bool AuthorizeMethod(uint32_t methodId, Args& args, const std::string& userId); +}; + +inline Manageable::~Manageable(void) {} + +}} + +#endif /*!_Manageable_*/ diff --git a/qpid/cpp/include/qpid/management/ManagementEvent.h b/qpid/cpp/include/qpid/management/ManagementEvent.h new file mode 100644 index 0000000000..e80175096f --- /dev/null +++ b/qpid/cpp/include/qpid/management/ManagementEvent.h @@ -0,0 +1,53 @@ +#ifndef _ManagementEvent_ +#define _ManagementEvent_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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/ManagementObject.h" +#include "qpid/types/Variant.h" +#include <string> + +namespace qpid { +namespace management { + +class ManagementAgent; + +class ManagementEvent : public ManagementItem { + public: + static const uint8_t MD5_LEN = 16; + //typedef void (*writeSchemaCall_t)(qpid::framing::Buffer&); + typedef void (*writeSchemaCall_t)(std::string&); + virtual ~ManagementEvent() {} + + virtual writeSchemaCall_t getWriteSchemaCall(void) = 0; + //virtual mapEncodeSchemaCall_t getMapEncodeSchemaCall(void) = 0; + virtual std::string& getEventName() const = 0; + virtual std::string& getPackageName() const = 0; + virtual uint8_t* getMd5Sum() const = 0; + virtual uint8_t getSeverity() const = 0; + virtual void encode(std::string&) const = 0; + virtual void mapEncode(qpid::types::Variant::Map&) const = 0; +}; + +}} + +#endif /*!_ManagementEvent_*/ diff --git a/qpid/cpp/include/qpid/management/ManagementObject.h b/qpid/cpp/include/qpid/management/ManagementObject.h new file mode 100644 index 0000000000..16bf21038c --- /dev/null +++ b/qpid/cpp/include/qpid/management/ManagementObject.h @@ -0,0 +1,237 @@ +#ifndef _ManagementObject_ +#define _ManagementObject_ + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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/CommonImportExport.h" + +#include "qpid/management/Mutex.h" +#include "qpid/types/Variant.h" + +#include <map> +#include <vector> + +namespace qpid { +namespace management { + +class Manageable; +class ObjectId; +class ManagementObject; + + +class AgentAttachment { + friend class ObjectId; +private: + uint64_t first; +public: + AgentAttachment() : first(0) {} + QPID_COMMON_EXTERN void setBanks(uint32_t broker, uint32_t bank); + uint64_t getFirst() const { return first; } +}; + + +class ObjectId { +protected: + const AgentAttachment* agent; + uint64_t first; + uint64_t second; + uint64_t agentEpoch; + std::string v2Key; + std::string agentName; + void fromString(const std::string&); +public: + QPID_COMMON_INLINE_EXTERN ObjectId() : agent(0), first(0), second(0), agentEpoch(0) {} + QPID_COMMON_INLINE_EXTERN ObjectId(const types::Variant& map) : + agent(0), first(0), second(0), agentEpoch(0) { mapDecode(map.asMap()); } + QPID_COMMON_EXTERN ObjectId(uint8_t flags, uint16_t seq, uint32_t broker); + QPID_COMMON_EXTERN ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq); + QPID_COMMON_EXTERN ObjectId(std::istream&); + QPID_COMMON_EXTERN ObjectId(const std::string&); + QPID_COMMON_INLINE_EXTERN ObjectId(const std::string& agentAddress, const std::string& key, + uint64_t epoch=0) : agent(0), first(0), second(0), + agentEpoch(epoch), v2Key(key), agentName(agentAddress) {} + + // Deprecated: + QPID_COMMON_EXTERN ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint64_t object); + QPID_COMMON_EXTERN bool operator==(const ObjectId &other) const; + QPID_COMMON_EXTERN bool operator<(const ObjectId &other) const; + QPID_COMMON_EXTERN void mapEncode(types::Variant::Map& map) const; + QPID_COMMON_EXTERN void mapDecode(const types::Variant::Map& map); + QPID_COMMON_EXTERN operator types::Variant::Map() const; + QPID_COMMON_INLINE_EXTERN uint32_t encodedSize() const { return 16; }; + QPID_COMMON_EXTERN void encode(std::string& buffer) const; + QPID_COMMON_EXTERN void decode(const std::string& buffer); + QPID_COMMON_EXTERN bool equalV1(const ObjectId &other) const; + QPID_COMMON_INLINE_EXTERN void setV2Key(const std::string& _key) { v2Key = _key; } + QPID_COMMON_EXTERN void setV2Key(const ManagementObject& object); + QPID_COMMON_INLINE_EXTERN void setAgentName(const std::string& _name) { agentName = _name; } + QPID_COMMON_INLINE_EXTERN const std::string& getAgentName() const { return agentName; } + QPID_COMMON_INLINE_EXTERN const std::string& getV2Key() const { return v2Key; } + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const ObjectId&); +}; + +class ManagementItem { +public: + static const uint8_t TYPE_U8 = 1; + static const uint8_t TYPE_U16 = 2; + static const uint8_t TYPE_U32 = 3; + static const uint8_t TYPE_U64 = 4; + static const uint8_t TYPE_SSTR = 6; + static const uint8_t TYPE_LSTR = 7; + static const uint8_t TYPE_ABSTIME = 8; + static const uint8_t TYPE_DELTATIME = 9; + static const uint8_t TYPE_REF = 10; + static const uint8_t TYPE_BOOL = 11; + static const uint8_t TYPE_FLOAT = 12; + static const uint8_t TYPE_DOUBLE = 13; + static const uint8_t TYPE_UUID = 14; + static const uint8_t TYPE_FTABLE = 15; + static const uint8_t TYPE_S8 = 16; + static const uint8_t TYPE_S16 = 17; + static const uint8_t TYPE_S32 = 18; + static const uint8_t TYPE_S64 = 19; + static const uint8_t TYPE_LIST = 21; + + static const uint8_t ACCESS_RC = 1; + static const uint8_t ACCESS_RW = 2; + static const uint8_t ACCESS_RO = 3; + + static const uint8_t DIR_I = 1; + static const uint8_t DIR_O = 2; + static const uint8_t DIR_IO = 3; + + static const uint8_t FLAG_CONFIG = 0x01; + static const uint8_t FLAG_INDEX = 0x02; + static const uint8_t FLAG_END = 0x80; + + const static uint8_t CLASS_KIND_TABLE = 1; + const static uint8_t CLASS_KIND_EVENT = 2; + + + +public: + virtual ~ManagementItem() {} +}; + +class QPID_COMMON_CLASS_EXTERN ManagementObject : public ManagementItem +{ +protected: + + uint64_t createTime; + uint64_t destroyTime; + uint64_t updateTime; + ObjectId objectId; + mutable bool configChanged; + mutable bool instChanged; + bool deleted; + Manageable* coreObject; + mutable Mutex accessLock; + uint32_t flags; + + static int nextThreadIndex; + bool forcePublish; + + QPID_COMMON_EXTERN int getThreadIndex(); + QPID_COMMON_EXTERN void writeTimestamps(std::string& buf) const; + QPID_COMMON_EXTERN void readTimestamps(const std::string& buf); + QPID_COMMON_EXTERN uint32_t writeTimestampsSize() const; + + public: + QPID_COMMON_EXTERN static const uint8_t MD5_LEN = 16; + QPID_COMMON_EXTERN static int maxThreads; + //typedef void (*writeSchemaCall_t) (qpid::framing::Buffer&); + typedef void (*writeSchemaCall_t) (std::string&); + + QPID_COMMON_EXTERN ManagementObject(Manageable* _core); + virtual ~ManagementObject() {} + + virtual writeSchemaCall_t getWriteSchemaCall() = 0; + virtual std::string getKey() const = 0; + + // Encode & Decode the property and statistics values + // for this object. + virtual void mapEncodeValues(types::Variant::Map& map, + bool includeProperties, + bool includeStatistics) = 0; + virtual void mapDecodeValues(const types::Variant::Map& map) = 0; + virtual void doMethod(std::string& methodName, + const types::Variant::Map& inMap, + types::Variant::Map& outMap, + const std::string& userId) = 0; + QPID_COMMON_EXTERN void writeTimestamps(types::Variant::Map& map) const; + QPID_COMMON_EXTERN void readTimestamps(const types::Variant::Map& buf); + + /** + * The following five methods are not pure-virtual because they will only + * be overridden in cases where QMFv1 is to be supported. + */ + virtual uint32_t writePropertiesSize() const { return 0; } + virtual void readProperties(const std::string&) {} + virtual void writeProperties(std::string&) const {} + virtual void writeStatistics(std::string&, bool = false) {} + virtual void doMethod(std::string&, const std::string&, std::string&, const std::string&) {} + + QPID_COMMON_EXTERN virtual void setReference(ObjectId objectId); + + virtual std::string& getClassName() const = 0; + virtual std::string& getPackageName() const = 0; + virtual uint8_t* getMd5Sum() const = 0; + + void setObjectId(ObjectId oid) { objectId = oid; } + ObjectId getObjectId() { return objectId; } + inline bool getConfigChanged() { return configChanged; } + virtual bool getInstChanged() { return instChanged; } + virtual bool hasInst() { return true; } + inline void setForcePublish(bool f) { forcePublish = f; } + inline bool getForcePublish() { return forcePublish; } + QPID_COMMON_EXTERN void setUpdateTime(); + QPID_COMMON_EXTERN void resourceDestroy(); + inline bool isDeleted() { return deleted; } + inline void setFlags(uint32_t f) { flags = f; } + inline uint32_t getFlags() { return flags; } + bool isSameClass(ManagementObject& other) { + for (int idx = 0; idx < MD5_LEN; idx++) + if (other.getMd5Sum()[idx] != getMd5Sum()[idx]) + return false; + return other.getClassName() == getClassName() && + other.getPackageName() == getPackageName(); + } + + // QPID_COMMON_EXTERN void encode(qpid::framing::Buffer& buf) const { writeProperties(buf); } + // QPID_COMMON_EXTERN void decode(qpid::framing::Buffer& buf) { readProperties(buf); } + //QPID_COMMON_EXTERN uint32_t encodedSize() const { return writePropertiesSize(); } + + // Encode/Decode the entire object as a map + //QPID_COMMON_EXTERN void mapEncode(types::Variant::Map& map, + //bool includeProperties=true, + //bool includeStatistics=true); + + //QPID_COMMON_EXTERN void mapDecode(const types::Variant::Map& map); +}; + +typedef std::map<ObjectId, ManagementObject*> ManagementObjectMap; +typedef std::vector<ManagementObject*> ManagementObjectVector; + +}} + + + +#endif /*!_ManagementObject_*/ diff --git a/qpid/cpp/include/qpid/management/Mutex.h b/qpid/cpp/include/qpid/management/Mutex.h new file mode 100644 index 0000000000..67ae04bae9 --- /dev/null +++ b/qpid/cpp/include/qpid/management/Mutex.h @@ -0,0 +1,67 @@ +#ifndef _management_Mutex_h +#define _management_Mutex_h + +/* + * + * Copyright (c) 2008 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/CommonImportExport.h" + +namespace qpid { + namespace sys { + class Mutex; + } + + namespace management { + + /** + * Scoped lock template: calls lock() in ctor, unlock() in dtor. + * L can be any class with lock() and unlock() functions. + */ + template <class L> class ScopedLockTemplate { + public: + ScopedLockTemplate(L& l) : mutex(l) { mutex.lock(); } + ~ScopedLockTemplate() { mutex.unlock(); } + private: + L& mutex; + }; + + template <class L> class ScopedUnlockTemplate { + public: + ScopedUnlockTemplate(L& l) : mutex(l) { mutex.unlock(); } + ~ScopedUnlockTemplate() { mutex.lock(); } + private: + L& mutex; + }; + + class Mutex { + public: + typedef ScopedLockTemplate<Mutex> ScopedLock; + typedef ScopedUnlockTemplate<Mutex> ScopedUnlock; + + QPID_COMMON_EXTERN Mutex(); + QPID_COMMON_EXTERN ~Mutex(); + QPID_COMMON_EXTERN void lock(); + QPID_COMMON_EXTERN void unlock(); + private: + sys::Mutex* impl; + }; + } +} + +#endif + diff --git a/qpid/cpp/include/qpid/messaging/Address.h b/qpid/cpp/include/qpid/messaging/Address.h new file mode 100644 index 0000000000..63dce0c49d --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Address.h @@ -0,0 +1,164 @@ +#ifndef QPID_MESSAGING_ADDRESS_H +#define QPID_MESSAGING_ADDRESS_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/messaging/ImportExport.h" + +#include "qpid/messaging/exceptions.h" +#include "qpid/types/Variant.h" + +#include <string> +#include <ostream> + +namespace qpid { +namespace messaging { + +class AddressImpl; + +/** \ingroup messaging + * Represents an address to which messages can be sent and from which + * messages can be received. Often a simple name is sufficient for + * this, however this can be augmented with a subject pattern and + * options. + * + * All parts of an address can be specified in a string of the + * following form: + * + * <address> [ / <subject> ] ; [ { <key> : <value> , ... } ] + * + * Here the <address> is a simple name for the addressed + * entity and <subject> is a subject or subject pattern for + * messages sent to or received from this address. The options are + * specified as a series of key value pairs enclosed in curly brackets + * (denoting a map). Values can be nested maps, or lists (which are + * denoted as a comma separated list of values inside square brackets, + * e.g. [a, b, c]). + * + * The currently supported options are as follows: + * + * <table border=0> + * + * <tr valign=top> + * <td>create</td> + * <td>Indicate whether the address should be automatically created + * or not. Can be one of <i>always</i>, <i>never</i>, + * <i>sender</i> or <i>receiver</i>. The properties of the node + * to be created can be specified via the node options (see + * below). + * </td> + * </tr> + * + * <tr valign=top> + * <td>assert</td> + * <td>Indicate whether or not to assert any specified node + * properties(see below) match the address. Can be one of + * <i>always</i>, <i>never</i>, <i>sender</i> or + * <i>receiver</i>. + * </td> + * </tr> + * + * <tr valign=top> + * <td>delete</td> + * <td>Indicate whether or not to delete the addressed node when a + * sender or receiver is cancelled. Can be one of <i>always</i>, + * <i>never</i>, <i>sender</i> or <i>receiver</i>. + * </td> + * </tr> + * + * <tr valign=top> + * <td>node</td> + + * <td>A nested map describing properties of the addressed + * node. Current properties supported are type (topic or queue), + * durable (boolean), x-declare and x-bindings. The x-declare + * option is a nested map in whcih protocol amqp 0-10 specific + * options for queue or exchange declare can be specified. The + * x-bindings option is a nested list, each element of which can + * specify a queue, an exchange, a binding-key and arguments, + * which are used to establish a binding on create. The node + * will be used if queue or exchange values are not specified. + * </td> + * </tr> + * + * <tr valign=top> + * <td>link</td> + * <td>A nested map through which properties of the 'link' from + * sender/receiver to node can be configured. Current propeties + * are name, durable, realiability, x-declare, x-subscribe and + * x-bindings. + * </td> + * </tr> + * + * For receivers there is one other option of interest: + * + * <table border=0 valign=top> + * <tr valign=top><td>mode</td><td>(only relevant for queues) + * indicates whether the subscribe should consume (the default) or + * merely browse the messages. Valid values are 'consume' and + * 'browse'</td></tr> + * </table> + * + * An address has value semantics. + */ +class QPID_MESSAGING_CLASS_EXTERN Address +{ + public: + QPID_MESSAGING_EXTERN Address(); + QPID_MESSAGING_EXTERN Address(const std::string& address); + QPID_MESSAGING_EXTERN Address(const std::string& name, const std::string& subject, + const qpid::types::Variant::Map& options, const std::string& type = ""); + QPID_MESSAGING_EXTERN Address(const Address& address); + QPID_MESSAGING_EXTERN ~Address(); + QPID_MESSAGING_EXTERN Address& operator=(const Address&); + QPID_MESSAGING_EXTERN const std::string& getName() const; + QPID_MESSAGING_EXTERN void setName(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getSubject() const; + QPID_MESSAGING_EXTERN void setSubject(const std::string&); + QPID_MESSAGING_EXTERN const qpid::types::Variant::Map& getOptions() const; + QPID_MESSAGING_EXTERN qpid::types::Variant::Map& getOptions(); + QPID_MESSAGING_EXTERN void setOptions(const qpid::types::Variant::Map&); + + QPID_MESSAGING_EXTERN std::string getType() const; + /** + * The type of and addressed node influences how receivers and + * senders are constructed for it. It also affects how a reply-to + * address is encoded. If the type is not specified in the address + * itself, it will be automatically determined by querying the + * broker. The type can be explicitly set to prevent this if + * needed. + */ + QPID_MESSAGING_EXTERN void setType(const std::string&); + + QPID_MESSAGING_EXTERN std::string str() const; + QPID_MESSAGING_EXTERN operator bool() const; + QPID_MESSAGING_EXTERN bool operator !() const; + private: + AddressImpl* impl; +}; + +#ifndef SWIG +QPID_MESSAGING_EXTERN std::ostream& operator<<(std::ostream& out, const Address& address); +#endif + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_ADDRESS_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Connection.h b/qpid/cpp/include/qpid/messaging/Connection.h new file mode 100644 index 0000000000..e938f23189 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Connection.h @@ -0,0 +1,114 @@ +#ifndef QPID_MESSAGING_CONNECTION_H +#define QPID_MESSAGING_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 "qpid/messaging/ImportExport.h" + +#include "qpid/messaging/Handle.h" +#include "qpid/messaging/exceptions.h" +#include "qpid/types/Variant.h" + +#include <string> + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif +class ConnectionImpl; +class Session; + +/** \ingroup messaging + * A connection represents a network connection to a remote endpoint. + */ + +class QPID_MESSAGING_CLASS_EXTERN Connection : public qpid::messaging::Handle<ConnectionImpl> +{ + public: + QPID_MESSAGING_EXTERN Connection(ConnectionImpl* impl); + QPID_MESSAGING_EXTERN Connection(const Connection&); + QPID_MESSAGING_EXTERN Connection(); + /** + * Current implementation supports the following options: + * + * username + * password + * heartbeat + * tcp-nodelay + * sasl-mechanism + * sasl-service + * sasl-min-ssf + * sasl-max-ssf + * transport + * + * Reconnect behaviour can be controlled through the following options: + * + * reconnect: true/false (enables/disables reconnect entirely) + * reconnect-timeout: number of seconds (give up and report failure after specified time) + * reconnect-limit: n (give up and report failure after specified number of attempts) + * reconnect-interval-min: number of seconds (initial delay between failed reconnection attempts) + * reconnect-interval-max: number of seconds (maximum delay between failed reconnection attempts) + * reconnect-interval: shorthand for setting the same reconnect_interval_min/max + * reconnect-urls: list of alternate urls to try when connecting + * + * The reconnect-interval is the time that the client waits + * for after a failed attempt to reconnect before retrying. It + * starts at the value of the min-retry-interval and is + * doubled every failure until the value of max-retry-interval + * is reached. + */ + QPID_MESSAGING_EXTERN Connection(const std::string& url, const qpid::types::Variant::Map& options = qpid::types::Variant::Map()); + /** + * Creates a connection using an option string of the form + * {name:value,name2:value2...}, see above for options supported. + * + * @exception InvalidOptionString if the string does not match the correct syntax + */ + QPID_MESSAGING_EXTERN Connection(const std::string& url, const std::string& options); + QPID_MESSAGING_EXTERN ~Connection(); + QPID_MESSAGING_EXTERN Connection& operator=(const Connection&); + QPID_MESSAGING_EXTERN void setOption(const std::string& name, const qpid::types::Variant& value); + QPID_MESSAGING_EXTERN void open(); + QPID_MESSAGING_EXTERN bool isOpen(); + QPID_MESSAGING_EXTERN bool isOpen() const; + /** + * Closes a connection and all sessions associated with it. An + * opened connection must be closed before the last handle is + * allowed to go out of scope. + */ + QPID_MESSAGING_EXTERN void close(); + QPID_MESSAGING_EXTERN Session createTransactionalSession(const std::string& name = std::string()); + QPID_MESSAGING_EXTERN Session createSession(const std::string& name = std::string()); + + QPID_MESSAGING_EXTERN Session getSession(const std::string& name) const; + QPID_MESSAGING_EXTERN std::string getAuthenticatedUsername(); + +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Connection>; +#endif +}; + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_CONNECTION_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Duration.h b/qpid/cpp/include/qpid/messaging/Duration.h new file mode 100644 index 0000000000..6b8f05c7c6 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Duration.h @@ -0,0 +1,57 @@ +#ifndef QPID_MESSAGING_DURATION_H +#define QPID_MESSAGING_DURATION_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/messaging/ImportExport.h" + +#include "qpid/sys/IntegerTypes.h" + +namespace qpid { +namespace messaging { + +/** \ingroup messaging + * A duration is a time in milliseconds. + */ +class QPID_MESSAGING_CLASS_EXTERN Duration +{ + public: + QPID_MESSAGING_EXTERN explicit Duration(uint64_t milliseconds); + QPID_MESSAGING_EXTERN uint64_t getMilliseconds() const; + QPID_MESSAGING_EXTERN static const Duration FOREVER; + QPID_MESSAGING_EXTERN static const Duration IMMEDIATE; + QPID_MESSAGING_EXTERN static const Duration SECOND; + QPID_MESSAGING_EXTERN static const Duration MINUTE; + private: + uint64_t milliseconds; +}; + +QPID_MESSAGING_EXTERN Duration operator*(const Duration& duration, + uint64_t multiplier); +QPID_MESSAGING_EXTERN Duration operator*(uint64_t multiplier, + const Duration& duration); +QPID_MESSAGING_EXTERN bool operator==(const Duration& a, const Duration& b); +QPID_MESSAGING_EXTERN bool operator!=(const Duration& a, const Duration& b); + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_DURATION_H*/ diff --git a/qpid/cpp/include/qpid/messaging/FailoverUpdates.h b/qpid/cpp/include/qpid/messaging/FailoverUpdates.h new file mode 100644 index 0000000000..6d7314620a --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/FailoverUpdates.h @@ -0,0 +1,49 @@ +#ifndef QPID_CLIENT_AMQP0_10_FAILOVERUPDATES_H +#define QPID_CLIENT_AMQP0_10_FAILOVERUPDATES_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/messaging/ImportExport.h" + +namespace qpid { +namespace messaging { +class Connection; +struct FailoverUpdatesImpl; + +/** + * A utility to listen for updates on cluster membership and update + * the list of known urls for a connection accordingly. + */ +class QPID_MESSAGING_CLASS_EXTERN FailoverUpdates +{ + public: + QPID_MESSAGING_EXTERN FailoverUpdates(Connection& connection); + QPID_MESSAGING_EXTERN ~FailoverUpdates(); + private: + FailoverUpdatesImpl* impl; + + //no need to copy instances of this class + FailoverUpdates(const FailoverUpdates&); + FailoverUpdates& operator=(const FailoverUpdates&); +}; +}} // namespace qpid::messaging + +#endif /*!QPID_CLIENT_AMQP0_10_FAILOVERUPDATES_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Handle.h b/qpid/cpp/include/qpid/messaging/Handle.h new file mode 100644 index 0000000000..97a8f00b54 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Handle.h @@ -0,0 +1,71 @@ +#ifndef QPID_MESSAGING_HANDLE_H +#define QPID_MESSAGING_HANDLE_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/messaging/ImportExport.h" + +namespace qpid { +namespace messaging { + +template <class> class PrivateImplRef; + +/** \ingroup messaging + * A handle is like a pointer: refers to an underlying implementation object. + * Copying the handle does not copy the object. + * + * Handles can be null, like a 0 pointer. Use isValid(), isNull() or the + * conversion to bool to test for a null handle. + */ +template <class T> class Handle { + public: + + /**@return true if handle is valid, i.e. not null. */ + QPID_MESSAGING_INLINE_EXTERN bool isValid() const { return impl; } + + /**@return true if handle is null. It is an error to call any function on a null handle. */ + QPID_MESSAGING_INLINE_EXTERN bool isNull() const { return !impl; } + + /** Conversion to bool supports idiom if (handle) { handle->... } */ + QPID_MESSAGING_INLINE_EXTERN operator bool() const { return impl; } + + /** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */ + QPID_MESSAGING_INLINE_EXTERN bool operator !() const { return !impl; } + + void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; } + + protected: + typedef T Impl; + QPID_MESSAGING_INLINE_EXTERN Handle() :impl() {} + + // Not implemented,subclasses must implement. + QPID_MESSAGING_EXTERN Handle(const Handle&); + QPID_MESSAGING_EXTERN Handle& operator=(const Handle&); + + Impl* impl; + + friend class PrivateImplRef<T>; +}; + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_HANDLE_H*/ diff --git a/qpid/cpp/include/qpid/messaging/ImportExport.h b/qpid/cpp/include/qpid/messaging/ImportExport.h new file mode 100644 index 0000000000..ab5f21f618 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/ImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_MESSAGING_IMPORTEXPORT_H +#define QPID_MESSAGING_IMPORTEXPORT_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/ImportExport.h" + +#if defined(CLIENT_EXPORT) || defined (qpidmessaging_EXPORTS) +# define QPID_MESSAGING_EXTERN QPID_EXPORT +# define QPID_MESSAGING_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_MESSAGING_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_MESSAGING_EXTERN QPID_IMPORT +# define QPID_MESSAGING_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_MESSAGING_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif /*!QPID_MESSAGING_IMPORTEXPORT_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Message.h b/qpid/cpp/include/qpid/messaging/Message.h new file mode 100644 index 0000000000..5cd978f2a2 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Message.h @@ -0,0 +1,166 @@ +#ifndef QPID_MESSAGING_MESSAGE_H +#define QPID_MESSAGING_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/messaging/ImportExport.h" + +#include "qpid/messaging/Duration.h" +#include "qpid/types/Exception.h" +#include "qpid/types/Variant.h" + +#include <string> + +namespace qpid { +namespace messaging { + +class Address; +class Codec; +struct MessageImpl; + +/** \ingroup messaging + * Representation of a message. + */ +class QPID_MESSAGING_CLASS_EXTERN Message +{ + public: + QPID_MESSAGING_EXTERN Message(const std::string& bytes = std::string()); + QPID_MESSAGING_EXTERN Message(const char*, size_t); + QPID_MESSAGING_EXTERN Message(const Message&); + QPID_MESSAGING_EXTERN ~Message(); + + QPID_MESSAGING_EXTERN Message& operator=(const Message&); + + QPID_MESSAGING_EXTERN void setReplyTo(const Address&); + QPID_MESSAGING_EXTERN const Address& getReplyTo() const; + + QPID_MESSAGING_EXTERN void setSubject(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getSubject() const; + + QPID_MESSAGING_EXTERN void setContentType(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getContentType() const; + + QPID_MESSAGING_EXTERN void setMessageId(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getMessageId() const; + + QPID_MESSAGING_EXTERN void setUserId(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getUserId() const; + + QPID_MESSAGING_EXTERN void setCorrelationId(const std::string&); + QPID_MESSAGING_EXTERN const std::string& getCorrelationId() const; + + QPID_MESSAGING_EXTERN void setPriority(uint8_t); + QPID_MESSAGING_EXTERN uint8_t getPriority() const; + + /** + * Set the time to live for this message in milliseconds. + */ + QPID_MESSAGING_EXTERN void setTtl(Duration ttl); + /** + *Get the time to live for this message in milliseconds. + */ + QPID_MESSAGING_EXTERN Duration getTtl() const; + + QPID_MESSAGING_EXTERN void setDurable(bool durable); + QPID_MESSAGING_EXTERN bool getDurable() const; + + QPID_MESSAGING_EXTERN bool getRedelivered() const; + QPID_MESSAGING_EXTERN void setRedelivered(bool); + + QPID_MESSAGING_EXTERN const qpid::types::Variant::Map& getProperties() const; + QPID_MESSAGING_EXTERN qpid::types::Variant::Map& getProperties(); + + QPID_MESSAGING_EXTERN void setContent(const std::string&); + /** + * Note that chars are copied. + */ + QPID_MESSAGING_EXTERN void setContent(const char* chars, size_t count); + + /** Get the content as a std::string */ + QPID_MESSAGING_EXTERN std::string getContent() const; + /** Get a const pointer to the start of the content data. */ + QPID_MESSAGING_EXTERN const char* getContentPtr() const; + /** Get the size of content in bytes. */ + QPID_MESSAGING_EXTERN size_t getContentSize() const; + + QPID_MESSAGING_EXTERN void setProperty(const std::string&, const qpid::types::Variant&); + private: + MessageImpl* impl; + friend struct MessageImplAccess; +}; + +struct QPID_MESSAGING_CLASS_EXTERN EncodingException : qpid::types::Exception +{ + QPID_MESSAGING_EXTERN EncodingException(const std::string& msg); +}; + +/** + * Decodes message content into a Variant::Map. + * + * @param message the message whose content should be decoded + * @param map the map into which the message contents will be decoded + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void decode(const Message& message, + qpid::types::Variant::Map& map, + const std::string& encoding = std::string()); +/** + * Decodes message content into a Variant::List. + * + * @param message the message whose content should be decoded + * @param list the list into which the message contents will be decoded + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void decode(const Message& message, + qpid::types::Variant::List& list, + const std::string& encoding = std::string()); +/** + * Encodes a Variant::Map into a message. + * + * @param map the map to be encoded + * @param message the message whose content should be set to the encoded map + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::Map& map, + Message& message, + const std::string& encoding = std::string()); +/** + * Encodes a Variant::List into a message. + * + * @param list the list to be encoded + * @param message the message whose content should be set to the encoded list + * @param encoding if specified, the encoding to use - this overrides + * any encoding specified by the content-type of the message + * @exception EncodingException + */ +QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::List& list, + Message& message, + const std::string& encoding = std::string()); + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_MESSAGE_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Receiver.h b/qpid/cpp/include/qpid/messaging/Receiver.h new file mode 100644 index 0000000000..13317dfcbd --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Receiver.h @@ -0,0 +1,144 @@ +#ifndef QPID_MESSAGING_RECEIVER_H +#define QPID_MESSAGING_RECEIVER_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/messaging/ImportExport.h" + +#include "qpid/messaging/exceptions.h" +#include "qpid/messaging/Handle.h" +#include "qpid/messaging/Duration.h" + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif + +class Message; +class ReceiverImpl; +class Session; + +/** \ingroup messaging + * Interface through which messages are received. + */ +class QPID_MESSAGING_CLASS_EXTERN Receiver : public qpid::messaging::Handle<ReceiverImpl> +{ + public: + QPID_MESSAGING_EXTERN Receiver(ReceiverImpl* impl = 0); + QPID_MESSAGING_EXTERN Receiver(const Receiver&); + QPID_MESSAGING_EXTERN ~Receiver(); + QPID_MESSAGING_EXTERN Receiver& operator=(const Receiver&); + /** + * Retrieves a message from this receivers local queue, or waits + * for upto the specified timeout for a message to become + * available. + */ + QPID_MESSAGING_EXTERN bool get(Message& message, Duration timeout=Duration::FOREVER); + /** + * Retrieves a message from this receivers local queue, or waits + * for up to the specified timeout for a message to become + * available. + * + * @exception NoMessageAvailable if there is no message to give + * after waiting for the specified timeout, or if the Receiver is + * closed, in which case isClose() will be true. + */ + QPID_MESSAGING_EXTERN Message get(Duration timeout=Duration::FOREVER); + /** + * Retrieves a message for this receivers subscription or waits + * for up to the specified timeout for one to become + * available. Unlike get() this method will check with the server + * that there is no message for the subscription this receiver is + * serving before returning false. + * + * @return false if there is no message to give after + * waiting for the specified timeout, or if the Receiver is + * closed, in which case isClose() will be true. + */ + QPID_MESSAGING_EXTERN bool fetch(Message& message, Duration timeout=Duration::FOREVER); + /** + * Retrieves a message for this receivers subscription or waits + * for up to the specified timeout for one to become + * available. Unlike get() this method will check with the server + * that there is no message for the subscription this receiver is + * serving before throwing an exception. + * + * @exception NoMessageAvailable if there is no message to give + * after waiting for the specified timeout, or if the Receiver is + * closed, in which case isClose() will be true. + */ + QPID_MESSAGING_EXTERN Message fetch(Duration timeout=Duration::FOREVER); + /** + * Sets the capacity for the receiver. The capacity determines how + * many incoming messages can be held in the receiver before being + * requested by a client via fetch() (or pushed to a listener). + */ + QPID_MESSAGING_EXTERN void setCapacity(uint32_t); + /** + * @return the capacity of the receiver. The capacity determines + * how many incoming messages can be held in the receiver before + * being requested by a client via fetch() (or pushed to a + * listener). + */ + QPID_MESSAGING_EXTERN uint32_t getCapacity(); + /** + * @return the number of messages received and waiting to be + * fetched. + */ + QPID_MESSAGING_EXTERN uint32_t getAvailable(); + /** + * @return a count of the number of messages received on this + * receiver that have been acknowledged, but for which that + * acknowledgement has not yet been confirmed as processed by the + * server. + */ + QPID_MESSAGING_EXTERN uint32_t getUnsettled(); + + /** + * Cancels this receiver. + */ + QPID_MESSAGING_EXTERN void close(); + + /** + * Return true if the receiver was closed by a call to close() + */ + QPID_MESSAGING_EXTERN bool isClosed() const; + + /** + * Returns the name of this receiver. + */ + QPID_MESSAGING_EXTERN const std::string& getName() const; + + /** + * Returns a handle to the session associated with this receiver. + */ + QPID_MESSAGING_EXTERN Session getSession() const; + +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Receiver>; +#endif +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_RECEIVER_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Sender.h b/qpid/cpp/include/qpid/messaging/Sender.h new file mode 100644 index 0000000000..8e1c5846e9 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Sender.h @@ -0,0 +1,99 @@ +#ifndef QPID_MESSAGING_SENDER_H +#define QPID_MESSAGING_SENDER_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/messaging/ImportExport.h" + +#include "qpid/messaging/Handle.h" +#include "qpid/sys/IntegerTypes.h" + +#include <string> + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif +class Message; +class SenderImpl; +class Session; +/** \ingroup messaging + * Interface through which messages are sent. + */ +class QPID_MESSAGING_CLASS_EXTERN Sender : public qpid::messaging::Handle<SenderImpl> +{ + public: + QPID_MESSAGING_EXTERN Sender(SenderImpl* impl = 0); + QPID_MESSAGING_EXTERN Sender(const Sender&); + QPID_MESSAGING_EXTERN ~Sender(); + QPID_MESSAGING_EXTERN Sender& operator=(const Sender&); + + /** + * Sends a message + * + * @param message the message to send + * @param sync if true the call will block until the server + * confirms receipt of the messages; if false will only block for + * available capacity (i.e. pending == capacity) + */ + QPID_MESSAGING_EXTERN void send(const Message& message, bool sync=false); + QPID_MESSAGING_EXTERN void close(); + + /** + * Sets the capacity for the sender. The capacity determines how + * many outgoing messages can be held pending confirmation of + * receipt by the broker. + */ + QPID_MESSAGING_EXTERN void setCapacity(uint32_t); + /** + * Returns the capacity of the sender. + * @see setCapacity + */ + QPID_MESSAGING_EXTERN uint32_t getCapacity(); + /** + * Returns the number of sent messages pending confirmation of + * receipt by the broker. (These are the 'in-doubt' messages). + */ + QPID_MESSAGING_EXTERN uint32_t getUnsettled(); + /** + * Returns the number of messages for which there is available + * capacity. + */ + QPID_MESSAGING_EXTERN uint32_t getAvailable(); + /** + * Returns the name of this sender. + */ + QPID_MESSAGING_EXTERN const std::string& getName() const; + + /** + * Returns a handle to the session associated with this sender. + */ + QPID_MESSAGING_EXTERN Session getSession() const; +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Sender>; +#endif +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_SENDER_H*/ diff --git a/qpid/cpp/include/qpid/messaging/Session.h b/qpid/cpp/include/qpid/messaging/Session.h new file mode 100644 index 0000000000..52786eb5f4 --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/Session.h @@ -0,0 +1,175 @@ +#ifndef QPID_MESSAGING_SESSION_H +#define QPID_MESSAGING_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/messaging/ImportExport.h" + +#include "qpid/messaging/exceptions.h" +#include "qpid/messaging/Duration.h" +#include "qpid/messaging/Handle.h" + +#include <string> + +namespace qpid { +namespace messaging { + +#ifndef SWIG +template <class> class PrivateImplRef; +#endif +class Address; +class Connection; +class Message; +class Sender; +class Receiver; +class SessionImpl; + +/** \ingroup messaging + * A session represents a distinct 'conversation' which can involve + * sending and receiving messages to and from different addresses. + */ +class QPID_MESSAGING_CLASS_EXTERN Session : public qpid::messaging::Handle<SessionImpl> +{ + public: + QPID_MESSAGING_EXTERN Session(SessionImpl* impl = 0); + QPID_MESSAGING_EXTERN Session(const Session&); + QPID_MESSAGING_EXTERN ~Session(); + QPID_MESSAGING_EXTERN Session& operator=(const Session&); + + /** + * Closes a session and all associated senders and receivers. An + * opened session should be closed before the last handle to it + * goes out of scope. All a connections sessions can be closed by + * a call to Connection::close(). + */ + QPID_MESSAGING_EXTERN void close(); + + QPID_MESSAGING_EXTERN void commit(); + QPID_MESSAGING_EXTERN void rollback(); + + /** + * Acknowledges all outstanding messages that have been received + * by the application on this session. + * + * @param sync if true, blocks until the acknowledgement has been + * processed by the server + */ + QPID_MESSAGING_EXTERN void acknowledge(bool sync=false); + /** + * Acknowledges the specified message. + */ + QPID_MESSAGING_EXTERN void acknowledge(Message&, bool sync=false); + /** + * Rejects the specified message. The broker does not redeliver a + * message that has been rejected. Once a message has been + * acknowledged, it can no longer be rejected. + */ + QPID_MESSAGING_EXTERN void reject(Message&); + /** + * Releases the specified message. The broker may redeliver the + * message. One a message has been acknowledged, it can no longer + * be released. + */ + QPID_MESSAGING_EXTERN void release(Message&); + + /** + * Request synchronisation with the server. + * + * @param block if true, this call will block until the server + * confirms completion of all pending operations; if false the + * call will request notification from the server but will return + * before receiving it. + */ + QPID_MESSAGING_EXTERN void sync(bool block=true); + + /** + * Returns the total number of messages received and waiting to be + * fetched by all Receivers belonging to this session. This is the + * total number of available messages across all receivers on this + * session. + */ + QPID_MESSAGING_EXTERN uint32_t getReceivable(); + /** + * Returns a count of the number of messages received this session + * that have been acknowledged, but for which that acknowledgement + * has not yet been confirmed as processed by the server. + */ + QPID_MESSAGING_EXTERN uint32_t getUnsettledAcks(); + /** + * Retrieves the receiver for the next available message. If there + * are no available messages at present the call will block for up + * to the specified timeout waiting for one to arrive. Returns + * true if a message was available at the point of return, in + * which case the passed in receiver reference will be set to the + * receiver for that message or false if no message was available. + */ + QPID_MESSAGING_EXTERN bool nextReceiver(Receiver&, Duration timeout=Duration::FOREVER); + /** + * Returns the receiver for the next available message. If there + * are no available messages at present the call will block for up + * to the specified timeout waiting for one to arrive. + * + * @exception Receiver::NoMessageAvailable if no message became + * available in time. + */ + QPID_MESSAGING_EXTERN Receiver nextReceiver(Duration timeout=Duration::FOREVER); + + /** + * Create a new sender through which messages can be sent to the + * specified address. + */ + QPID_MESSAGING_EXTERN Sender createSender(const Address& address); + QPID_MESSAGING_EXTERN Sender createSender(const std::string& address); + + /** + * Create a new receiver through which messages can be received + * from the specified address. + */ + QPID_MESSAGING_EXTERN Receiver createReceiver(const Address& address); + QPID_MESSAGING_EXTERN Receiver createReceiver(const std::string& address); + + /** + * Returns the sender with the specified name. + *@exception KeyError if there is none for that name. + */ + QPID_MESSAGING_EXTERN Sender getSender(const std::string& name) const; + /** + * Returns the receiver with the specified name. + *@exception KeyError if there is none for that name. + */ + QPID_MESSAGING_EXTERN Receiver getReceiver(const std::string& name) const; + /** + * Returns a handle to the connection this session is associated + * with. + */ + QPID_MESSAGING_EXTERN Connection getConnection() const; + + QPID_MESSAGING_EXTERN bool hasError(); + QPID_MESSAGING_EXTERN void checkError(); + +#ifndef SWIG + private: + friend class qpid::messaging::PrivateImplRef<Session>; +#endif +}; +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_SESSION_H*/ diff --git a/qpid/cpp/include/qpid/messaging/exceptions.h b/qpid/cpp/include/qpid/messaging/exceptions.h new file mode 100644 index 0000000000..07d1dc414b --- /dev/null +++ b/qpid/cpp/include/qpid/messaging/exceptions.h @@ -0,0 +1,153 @@ +#ifndef QPID_MESSAGING_EXCEPTIONS_H +#define QPID_MESSAGING_EXCEPTIONS_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/messaging/ImportExport.h" +#include "qpid/types/Exception.h" +#include "qpid/types/Variant.h" + +namespace qpid { +namespace messaging { + +/** \ingroup messaging + */ + +struct QPID_MESSAGING_CLASS_EXTERN MessagingException : public qpid::types::Exception +{ + QPID_MESSAGING_EXTERN MessagingException(const std::string& msg); + QPID_MESSAGING_EXTERN virtual ~MessagingException() throw(); + + qpid::types::Variant::Map detail; + //TODO: override what() to include detail if present +}; + +struct QPID_MESSAGING_CLASS_EXTERN InvalidOptionString : public MessagingException +{ + QPID_MESSAGING_EXTERN InvalidOptionString(const std::string& msg); +}; + +struct QPID_MESSAGING_CLASS_EXTERN KeyError : public MessagingException +{ + QPID_MESSAGING_EXTERN KeyError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN LinkError : public MessagingException +{ + QPID_MESSAGING_EXTERN LinkError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN AddressError : public LinkError +{ + QPID_MESSAGING_EXTERN AddressError(const std::string&); +}; + +/** + * Thrown when a syntactically correct address cannot be resolved or + * used. + */ +struct QPID_MESSAGING_CLASS_EXTERN ResolutionError : public AddressError +{ + QPID_MESSAGING_EXTERN ResolutionError(const std::string& msg); +}; + +struct QPID_MESSAGING_CLASS_EXTERN AssertionFailed : public ResolutionError +{ + QPID_MESSAGING_EXTERN AssertionFailed(const std::string& msg); +}; + +struct QPID_MESSAGING_CLASS_EXTERN NotFound : public ResolutionError +{ + QPID_MESSAGING_EXTERN NotFound(const std::string& msg); +}; + +/** + * Thrown when an address string with inalid sytanx is used. + */ +struct QPID_MESSAGING_CLASS_EXTERN MalformedAddress : public AddressError +{ + QPID_MESSAGING_EXTERN MalformedAddress(const std::string& msg); +}; + +struct QPID_MESSAGING_CLASS_EXTERN ReceiverError : public LinkError +{ + QPID_MESSAGING_EXTERN ReceiverError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN FetchError : public ReceiverError +{ + QPID_MESSAGING_EXTERN FetchError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN NoMessageAvailable : public FetchError +{ + QPID_MESSAGING_EXTERN NoMessageAvailable(); +}; + +struct QPID_MESSAGING_CLASS_EXTERN SenderError : public LinkError +{ + QPID_MESSAGING_EXTERN SenderError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN SendError : public SenderError +{ + QPID_MESSAGING_EXTERN SendError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN TargetCapacityExceeded : public SendError +{ + QPID_MESSAGING_EXTERN TargetCapacityExceeded(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN SessionError : public MessagingException +{ + QPID_MESSAGING_EXTERN SessionError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN TransactionError : public SessionError +{ + QPID_MESSAGING_EXTERN TransactionError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN TransactionAborted : public TransactionError +{ + QPID_MESSAGING_EXTERN TransactionAborted(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN UnauthorizedAccess : public SessionError +{ + QPID_MESSAGING_EXTERN UnauthorizedAccess(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN ConnectionError : public MessagingException +{ + QPID_MESSAGING_EXTERN ConnectionError(const std::string&); +}; + +struct QPID_MESSAGING_CLASS_EXTERN TransportFailure : public MessagingException +{ + QPID_MESSAGING_EXTERN TransportFailure(const std::string&); +}; + +}} // namespace qpid::messaging + +#endif /*!QPID_MESSAGING_EXCEPTIONS_H*/ diff --git a/qpid/cpp/include/qpid/sys/Condition.h b/qpid/cpp/include/qpid/sys/Condition.h new file mode 100644 index 0000000000..9be4b357fe --- /dev/null +++ b/qpid/cpp/include/qpid/sys/Condition.h @@ -0,0 +1,33 @@ +#ifndef _sys_Condition_h +#define _sys_Condition_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. + * + */ + +#ifdef USE_APR_PLATFORM +#include "apr/Condition.h" +#elif defined (_WIN32) +#include "windows/Condition.h" +#else +#include "posix/Condition.h" +#endif + +#endif /*!_sys_Condition_h*/ diff --git a/qpid/cpp/include/qpid/sys/ExceptionHolder.h b/qpid/cpp/include/qpid/sys/ExceptionHolder.h new file mode 100644 index 0000000000..4bc934cf75 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/ExceptionHolder.h @@ -0,0 +1,71 @@ +#ifndef QPID_EXCEPTIONHOLDER_H +#define QPID_EXCEPTIONHOLDER_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 sys { + +struct Raisable { + virtual ~Raisable() {}; + virtual void raise() const=0; + virtual std::string what() const=0; +}; + +/** + * Holder for exceptions. Allows the thread that notices an error condition to + * create an exception and store it to be thrown by another thread. + */ +class ExceptionHolder : public Raisable { + public: + ExceptionHolder() {} + // Use default copy & assign. + + /** Take ownership of ex */ + template <class Ex> ExceptionHolder(Ex* ex) { wrap(ex); } + template <class Ex> ExceptionHolder& operator=(Ex* ex) { wrap(ex); return *this; } + + void raise() const { if (wrapper.get()) wrapper->raise() ; } + std::string what() const { return wrapper.get() ? wrapper->what() : std::string(); } + bool empty() const { return !wrapper.get(); } + operator bool() const { return !empty(); } + void reset() { wrapper.reset(); } + + private: + template <class Ex> struct Wrapper : public Raisable { + Wrapper(Ex* ptr) : exception(ptr) {} + void raise() const { throw *exception; } + std::string what() const { return exception->what(); } + boost::shared_ptr<Ex> exception; + }; + template <class Ex> void wrap(Ex* ex) { wrapper.reset(new Wrapper<Ex>(ex)); } + boost::shared_ptr<Raisable> wrapper; +}; + + +}} // namespace qpid::sys + + +#endif /*!QPID_EXCEPTIONHOLDER_H*/ diff --git a/qpid/cpp/include/qpid/sys/IOHandle.h b/qpid/cpp/include/qpid/sys/IOHandle.h new file mode 100644 index 0000000000..45fc8c240a --- /dev/null +++ b/qpid/cpp/include/qpid/sys/IOHandle.h @@ -0,0 +1,49 @@ +#ifndef _sys_IOHandle_h +#define _sys_IOHandle_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/CommonImportExport.h" + +namespace qpid { +namespace sys { + +/** + * This is a class intended to abstract the Unix concept of file descriptor + * or the Windows concept of HANDLE + */ +class PollerHandle; +class IOHandlePrivate; +class IOHandle { + friend class PollerHandle; + friend class IOHandlePrivate; + +protected: + IOHandlePrivate* const impl; + + IOHandle(IOHandlePrivate*); + QPID_COMMON_EXTERN virtual ~IOHandle(); +}; + +}} + +#endif // _sys_IOHandle_h diff --git a/qpid/cpp/include/qpid/sys/IntegerTypes.h b/qpid/cpp/include/qpid/sys/IntegerTypes.h new file mode 100755 index 0000000000..75fa921de0 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/IntegerTypes.h @@ -0,0 +1,31 @@ +#ifndef QPID_SYS_INTEGERTYPES_H +#define QPID_SYS_INTEGERTYPES_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(_WINDOWS) || defined (WIN32)) +#include "qpid/sys/windows/IntegerTypes.h" +#endif +#if !defined _WINDOWS && !defined WIN32 +#include "qpid/sys/posix/IntegerTypes.h" +#endif + +#endif /*!QPID_SYS_INTEGERTYPES_H*/ diff --git a/qpid/cpp/include/qpid/sys/Monitor.h b/qpid/cpp/include/qpid/sys/Monitor.h new file mode 100644 index 0000000000..123bf92dcb --- /dev/null +++ b/qpid/cpp/include/qpid/sys/Monitor.h @@ -0,0 +1,49 @@ +#ifndef _sys_Monitor_h +#define _sys_Monitor_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/Condition.h" + +namespace qpid { +namespace sys { + +/** + * A monitor is a condition variable and a mutex + */ +class Monitor : public Mutex, public Condition { + public: + inline void wait(); + inline bool wait(const AbsTime& absoluteTime); +}; + + +void Monitor::wait() { + Condition::wait(*this); +} + +bool Monitor::wait(const AbsTime& absoluteTime) { + return Condition::wait(*this, absoluteTime); +} + +}} +#endif /*!_sys_Monitor_h*/ diff --git a/qpid/cpp/include/qpid/sys/Mutex.h b/qpid/cpp/include/qpid/sys/Mutex.h new file mode 100644 index 0000000000..43a83d4fc3 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/Mutex.h @@ -0,0 +1,91 @@ +#ifndef _sys_Mutex_h +#define _sys_Mutex_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. + * + */ + +namespace qpid { +namespace sys { + +/** + * Scoped lock template: calls lock() in ctor, unlock() in dtor. + * L can be any class with lock() and unlock() functions. + */ +template <class L> +class ScopedLock +{ + public: + ScopedLock(L& l) : mutex(l) { l.lock(); } + ~ScopedLock() { mutex.unlock(); } + private: + L& mutex; +}; + +template <class L> +class ScopedUnlock +{ + public: + ScopedUnlock(L& l) : mutex(l) { l.unlock(); } + ~ScopedUnlock() { mutex.lock(); } + private: + L& mutex; +}; + +template <class L> +class ScopedRlock +{ + public: + ScopedRlock(L& l) : mutex(l) { l.rlock(); } + ~ScopedRlock() { mutex.unlock(); } + private: + L& mutex; +}; + +template <class L> +class ScopedWlock +{ + public: + ScopedWlock(L& l) : mutex(l) { l.wlock(); } + ~ScopedWlock() { mutex.unlock(); } + private: + L& mutex; +}; + +template <class L> +class ConditionalScopedLock +{ + public: + ConditionalScopedLock(L& l) : mutex(l) { acquired = l.trylock(); } + ~ConditionalScopedLock() { if (acquired) mutex.unlock(); } + bool lockAcquired() { return acquired; } + private: + L& mutex; + bool acquired; +}; + +}} + +#ifdef USE_APR_PLATFORM +#include "apr/Mutex.h" +#elif defined (_WIN32) +#include "windows/Mutex.h" +#else +#include "posix/Mutex.h" +#endif + +#endif /*!_sys_Mutex_h*/ diff --git a/qpid/cpp/include/qpid/sys/Runnable.h b/qpid/cpp/include/qpid/sys/Runnable.h new file mode 100644 index 0000000000..fed7663cb6 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/Runnable.h @@ -0,0 +1,51 @@ +#ifndef _Runnable_ +#define _Runnable_ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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> +#include "qpid/CommonImportExport.h" + +namespace qpid { +namespace sys { + +/** + * Interface for objects that can be run, e.g. in a thread. + */ +class QPID_COMMON_CLASS_EXTERN Runnable +{ + public: + /** Type to represent a runnable as a Functor */ + typedef boost::function0<void> Functor; + + QPID_COMMON_EXTERN virtual ~Runnable(); + + /** Derived classes override run(). */ + virtual void run() = 0; + + /** Create a functor object that will call this->run(). */ + Functor functor(); +}; + +}} + + +#endif diff --git a/qpid/cpp/include/qpid/sys/StrError.h b/qpid/cpp/include/qpid/sys/StrError.h new file mode 100644 index 0000000000..36489dd0fc --- /dev/null +++ b/qpid/cpp/include/qpid/sys/StrError.h @@ -0,0 +1,36 @@ +#ifndef _sys_StrError_h +#define _sys_StrError_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/CommonImportExport.h" + +namespace qpid { +namespace sys { + +/** Get the error message for a system number err, e.g. errno. */ +QPID_COMMON_EXTERN std::string strError(int err); + +}} // namespace qpid + +#endif // _sys_StrError_h diff --git a/qpid/cpp/include/qpid/sys/SystemInfo.h b/qpid/cpp/include/qpid/sys/SystemInfo.h new file mode 100644 index 0000000000..23594cf650 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/SystemInfo.h @@ -0,0 +1,86 @@ +#ifndef QPID_SYS_SYSTEMINFO_H +#define QPID_SYS_SYSTEMINFO_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/IntegerTypes.h" +#include "qpid/Address.h" +#include "qpid/CommonImportExport.h" +#include <vector> + +namespace qpid { +namespace sys { + +/** + * Retrieve information about the system we are running on. + * Results may be dependent on OS/hardware. + */ +namespace SystemInfo { + /** + * Estimate available concurrency, e.g. number of CPU cores. + * -1 means estimate not available on this platform. + */ + QPID_COMMON_EXTERN long concurrency(); + + /** + * Get the local host name and set it in the specified. + * Returns false if it can't be obtained and sets errno to any error value. + */ + QPID_COMMON_EXTERN bool getLocalHostname (Address &address); + + QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList); + + /** + * Retrieve system identifiers and versions. This is information that can + * generally be retrieved via POSIX uname(). + * + * @param osName Receives the OS name; e.g., GNU/Linux or Windows + * @param nodeName Receives the nodename. This may or may not match the + * set hostname from getLocalHostname(). + * @param release Receives the OS release identifier. + * @param version Receives the OS release version (kernel, build, sp, etc.) + * @param machine Receives the hardware type. + */ + QPID_COMMON_EXTERN void getSystemId (std::string &osName, + std::string &nodeName, + std::string &release, + std::string &version, + std::string &machine); + + /** + * Get the process ID of the current process. + */ + QPID_COMMON_EXTERN uint32_t getProcessId(); + + /** + * Get the process ID of the parent of the current process. + */ + QPID_COMMON_EXTERN uint32_t getParentProcessId(); + + /** + * Get the name of the current process (i.e. the name of the executable) + */ + QPID_COMMON_EXTERN std::string getProcessName(); + + +}}} // namespace qpid::sys::SystemInfo + +#endif /*!QPID_SYS_SYSTEMINFO_H*/ diff --git a/qpid/cpp/include/qpid/sys/Thread.h b/qpid/cpp/include/qpid/sys/Thread.h new file mode 100644 index 0000000000..f556612908 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/Thread.h @@ -0,0 +1,71 @@ +#ifndef _sys_Thread_h +#define _sys_Thread_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/CommonImportExport.h" + +#ifdef _WIN32 +# ifdef _MSC_VER +# define QPID_TSS __declspec(thread) +# else +# define QPID_TSS __thread +# endif +#elif defined (__GNUC__) +# define QPID_TSS __thread +#elif defined (__SUNPRO_CC) +# define QPID_TSS __thread +#else +# error "Dont know how to define QPID_TSS for this platform" +#endif + +namespace qpid { +namespace sys { + +class Runnable; +class ThreadPrivate; + +class Thread +{ + boost::shared_ptr<ThreadPrivate> impl; + + public: + QPID_COMMON_EXTERN Thread(); + QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable*); + QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable&); + + QPID_COMMON_EXTERN operator bool(); + QPID_COMMON_EXTERN bool operator==(const Thread&) const; + QPID_COMMON_EXTERN bool operator!=(const Thread&) const; + + QPID_COMMON_EXTERN void join(); + + QPID_COMMON_EXTERN static Thread current(); + + /** ID of current thread for logging. + * Workaround for broken Thread::current() in APR + */ + QPID_COMMON_EXTERN static unsigned long logId(); +}; + +}} +#endif /*!_sys_Thread_h*/ diff --git a/qpid/cpp/include/qpid/sys/Time.h b/qpid/cpp/include/qpid/sys/Time.h new file mode 100644 index 0000000000..9c5ac66e9a --- /dev/null +++ b/qpid/cpp/include/qpid/sys/Time.h @@ -0,0 +1,175 @@ +#ifndef _sys_Time_h +#define _sys_Time_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/IntegerTypes.h" +/* + * The platform defines its notion of time as a TimePrivate type. The + * platform's implementation knows how to handle this type. + */ +#if defined (_WIN32) +# include "windows/Time.h" +#else +# include "posix/Time.h" +#endif + +#include "qpid/CommonImportExport.h" + +#include <limits> +#include <iosfwd> + +namespace qpid { +namespace sys { + +class Duration; + +/** + * @class AbsTime + * + * Class to represent an instant in time. + * + * The time resolution is in nanosecs, and this is held with 64 bits + * giving a total time span from about 25 million years ago to 25 million + * years hence. As an aside the internal time can sensibly be negative + * meaning before the epoch (probably 1/1/1970 although this class doesn't + * care). + * + * The AbsTime class is a value class and so you don't need to add any + * accessors to its internal state. If you think you want to replace its value, + * you need to construct a new AbsTime and assign it, viz: + * + * AbsTime when = now(); + * ... + * when = AbsTime(when, 2*TIME_SEC); // Advance timer 2 secs + * + * AbsTime is not intended to be used to represent calendar dates/times + * but you can construct a Duration since the Unix Epoch, 1970-1-1-00:00, + * so that you can convert to a date/time if needed: + * + * int64_t nanosec_since_epoch = Duration(EPOCH, now()); + * + * There are some sensible operations that are currently missing from + * AbsTime, but nearly all that's needed can be done with a mixture of + * AbsTimes and Durations. + * + * For example, convenience operators to add a Duration and AbsTime returning + * an AbsTime would fit here (although you can already perform the operation + * with one of the AbsTime constructors). However trying to add 2 AbsTimes + * doesn't make sense. + */ +class AbsTime { + friend class Duration; + friend class Condition; + + TimePrivate timepoint; + +public: + + inline AbsTime() : timepoint() {} + QPID_COMMON_EXTERN AbsTime(const AbsTime& time0, const Duration& duration); + // Default assignment operation fine + // Default copy constructor fine + + QPID_COMMON_EXTERN static AbsTime now(); + QPID_COMMON_EXTERN static AbsTime FarFuture(); + QPID_COMMON_EXTERN static AbsTime Epoch(); + + bool operator==(const AbsTime& t) const { return t.timepoint == timepoint; } + + friend bool operator<(const AbsTime& a, const AbsTime& b); + friend bool operator>(const AbsTime& a, const AbsTime& b); + QPID_COMMON_EXTERN friend std::ostream& operator << (std::ostream&, const AbsTime&); +}; + +QPID_COMMON_EXTERN std::ostream& operator << (std::ostream&, const AbsTime&); + +/** + * @class Duration + * Class to represent the duration between instants of time. + * + * As AbsTime, this class also uses nanosecs for its time + * resolution where possible. For the most part a duration can be dealt + * with like a 64 bit integer, and indeed there is an implicit conversion which + * makes this quite convenient. + */ +class Duration { + static int64_t max() { return std::numeric_limits<int64_t>::max(); } + int64_t nanosecs; + + friend class AbsTime; + +public: + QPID_COMMON_INLINE_EXTERN inline Duration(int64_t time0 = 0); + QPID_COMMON_EXTERN explicit Duration(const AbsTime& start, const AbsTime& finish); + inline operator int64_t() const; +}; + +std::ostream& operator << (std::ostream&, const Duration&); + +inline AbsTime now() { return AbsTime::now(); } + +inline bool operator<(const AbsTime& a, const AbsTime& b) +{ return a.timepoint < b.timepoint; } +inline bool operator>(const AbsTime& a, const AbsTime& b) +{ return a.timepoint > b.timepoint; } + +Duration::Duration(int64_t time0) : + nanosecs(time0) +{} + +Duration::operator int64_t() const +{ return nanosecs; } + +/** Nanoseconds per second. */ +const Duration TIME_SEC = 1000*1000*1000; +/** Nanoseconds per millisecond */ +const Duration TIME_MSEC = 1000*1000; +/** Nanoseconds per microseconds. */ +const Duration TIME_USEC = 1000; +/** Nanoseconds per nanosecond. */ +const Duration TIME_NSEC = 1; + +/** Value to represent an infinite timeout */ +const Duration TIME_INFINITE = std::numeric_limits<int64_t>::max(); + +/** Absolute time point for the Unix epoch: 1970-01-01T00:00:00 */ +const AbsTime EPOCH = AbsTime::Epoch(); + +/** Time greater than any other time */ +const AbsTime FAR_FUTURE = AbsTime::FarFuture(); + +/** Portable sleep for a number of seconds */ +QPID_COMMON_EXTERN void sleep(int secs); + +/** Portable sleep for a number of microseconds */ +QPID_COMMON_EXTERN void usleep(uint64_t usecs); + +/** Output formatted date/time for now*/ +void outputFormattedNow(std::ostream&); + +/** Output unformatted nanosecond-resolution time for now */ +void outputHiresNow(std::ostream&); + +}} + +#endif /*!_sys_Time_h*/ diff --git a/qpid/cpp/include/qpid/sys/posix/Condition.h b/qpid/cpp/include/qpid/sys/posix/Condition.h new file mode 100644 index 0000000000..36e7557ffd --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/Condition.h @@ -0,0 +1,86 @@ +#ifndef _sys_posix_Condition_h +#define _sys_posix_Condition_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/posix/PrivatePosix.h" + +#include "qpid/sys/Mutex.h" +#include "qpid/sys/Time.h" + +#include <time.h> +#include <sys/errno.h> +#include <boost/noncopyable.hpp> + +namespace qpid { +namespace sys { + +/** + * A condition variable for thread synchronization. + */ +class Condition +{ + public: + inline Condition(); + inline ~Condition(); + inline void wait(Mutex&); + inline bool wait(Mutex&, const AbsTime& absoluteTime); + inline void notify(); + inline void notifyAll(); + + private: + pthread_cond_t condition; +}; + +Condition::Condition() { + QPID_POSIX_ASSERT_THROW_IF(pthread_cond_init(&condition, 0)); +} + +Condition::~Condition() { + QPID_POSIX_ABORT_IF(pthread_cond_destroy(&condition)); +} + +void Condition::wait(Mutex& mutex) { + QPID_POSIX_ASSERT_THROW_IF(pthread_cond_wait(&condition, &mutex.mutex)); +} + +bool Condition::wait(Mutex& mutex, const AbsTime& absoluteTime){ + struct timespec ts; + toTimespec(ts, Duration(EPOCH, absoluteTime)); + int status = pthread_cond_timedwait(&condition, &mutex.mutex, &ts); + if (status != 0) { + if (status == ETIMEDOUT) return false; + throw QPID_POSIX_ERROR(status); + } + return true; +} + +void Condition::notify(){ + QPID_POSIX_ASSERT_THROW_IF(pthread_cond_signal(&condition)); +} + +void Condition::notifyAll(){ + QPID_POSIX_ASSERT_THROW_IF(pthread_cond_broadcast(&condition)); +} + +}} +#endif /*!_sys_posix_Condition_h*/ diff --git a/qpid/cpp/include/qpid/sys/posix/IntegerTypes.h b/qpid/cpp/include/qpid/sys/posix/IntegerTypes.h new file mode 100755 index 0000000000..ce97f7bde8 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/IntegerTypes.h @@ -0,0 +1,26 @@ +#ifndef QPID_SYS_POSIX_INTEGERTYPES_H +#define QPID_SYS_POSIX_INTEGERTYPES_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 <stdint.h> + +#endif /*!QPID_SYS_INTEGERTYPES_H*/ diff --git a/qpid/cpp/include/qpid/sys/posix/Mutex.h b/qpid/cpp/include/qpid/sys/posix/Mutex.h new file mode 100644 index 0000000000..e2b21b5a56 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/Mutex.h @@ -0,0 +1,158 @@ +#ifndef _sys_posix_Mutex_h +#define _sys_posix_Mutex_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/posix/check.h" + +#include <pthread.h> +#include <boost/noncopyable.hpp> + +namespace qpid { +namespace sys { + +class Condition; + +/** + * Mutex lock. + */ +class Mutex : private boost::noncopyable { + friend class Condition; + static const pthread_mutexattr_t* getAttribute(); + +public: + typedef ::qpid::sys::ScopedLock<Mutex> ScopedLock; + typedef ::qpid::sys::ScopedUnlock<Mutex> ScopedUnlock; + + inline Mutex(); + inline ~Mutex(); + inline void lock(); + inline void unlock(); + inline bool trylock(); + + +protected: + pthread_mutex_t mutex; +}; + +/** + * RW lock. + */ +class RWlock : private boost::noncopyable { + friend class Condition; + +public: + typedef ::qpid::sys::ScopedRlock<RWlock> ScopedRlock; + typedef ::qpid::sys::ScopedWlock<RWlock> ScopedWlock; + + inline RWlock(); + inline ~RWlock(); + inline void wlock(); // will write-lock + inline void rlock(); // will read-lock + inline void unlock(); + inline void trywlock(); // will write-try + inline void tryrlock(); // will read-try + +protected: + pthread_rwlock_t rwlock; +}; + + +/** + * PODMutex is a POD, can be static-initialized with + * PODMutex m = QPID_PODMUTEX_INITIALIZER + */ +struct PODMutex +{ + typedef ::qpid::sys::ScopedLock<PODMutex> ScopedLock; + + inline void lock(); + inline void unlock(); + inline bool trylock(); + + // Must be public to be a POD: + pthread_mutex_t mutex; +}; + +#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } + +void PODMutex::lock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_lock(&mutex)); +} + +void PODMutex::unlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_unlock(&mutex)); +} + +bool PODMutex::trylock() { + return pthread_mutex_trylock(&mutex) == 0; +} + +Mutex::Mutex() { + QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_init(&mutex, getAttribute())); +} + +Mutex::~Mutex(){ + QPID_POSIX_ABORT_IF(pthread_mutex_destroy(&mutex)); +} + +void Mutex::lock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_lock(&mutex)); +} + +void Mutex::unlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_mutex_unlock(&mutex)); +} + +bool Mutex::trylock() { + return pthread_mutex_trylock(&mutex) == 0; +} + + +RWlock::RWlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_init(&rwlock, NULL)); +} + +RWlock::~RWlock(){ + QPID_POSIX_ABORT_IF(pthread_rwlock_destroy(&rwlock)); +} + +void RWlock::wlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_wrlock(&rwlock)); +} + +void RWlock::rlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_rdlock(&rwlock)); +} + +void RWlock::unlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_unlock(&rwlock)); +} + +void RWlock::trywlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_trywrlock(&rwlock)); +} + +void RWlock::tryrlock() { + QPID_POSIX_ASSERT_THROW_IF(pthread_rwlock_tryrdlock(&rwlock)); +} + + +}} +#endif /*!_sys_posix_Mutex_h*/ diff --git a/qpid/cpp/include/qpid/sys/posix/PrivatePosix.h b/qpid/cpp/include/qpid/sys/posix/PrivatePosix.h new file mode 100644 index 0000000000..79cb950275 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/PrivatePosix.h @@ -0,0 +1,77 @@ +#ifndef _sys_posix_PrivatePosix_h +#define _sys_posix_PrivatePosix_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/IOHandle.h" + +struct timespec; +struct timeval; +struct addrinfo; + +namespace qpid { +namespace sys { + +// Private Time related implementation details +struct timespec& toTimespec(struct timespec& ts, const Duration& t); +struct timeval& toTimeval(struct timeval& tv, const Duration& t); +Duration toTime(const struct timespec& ts); + +// Private SocketAddress details +class SocketAddress; +const struct addrinfo& getAddrInfo(const SocketAddress&); + +// Private fd related implementation details +class IOHandlePrivate { +public: + IOHandlePrivate(int f = -1) : + fd(f) + {} + + int fd; +}; + +int toFd(const IOHandlePrivate* h); + +// Posix fd as an IOHandle +class PosixIOHandle : public IOHandle { +public: + PosixIOHandle(int fd) : + IOHandle(new IOHandlePrivate(fd)) + {} +}; + +// Dummy IOHandle for places it's required in the API +// but we promise not to actually try to do any operations on the IOHandle +class NullIOHandle : public IOHandle { +public: + NullIOHandle() : + IOHandle(new IOHandlePrivate) + {} +}; + +extern NullIOHandle DummyIOHandle; + +}} + +#endif /*!_sys_posix_PrivatePosix_h*/ diff --git a/qpid/cpp/include/qpid/sys/posix/Time.h b/qpid/cpp/include/qpid/sys/posix/Time.h new file mode 100755 index 0000000000..62d734c816 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/Time.h @@ -0,0 +1,34 @@ +#ifndef QPID_SYS_POSIX_TIME_H +#define QPID_SYS_POSIX_TIME_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" + +namespace qpid { +namespace sys { + +/** + * Class to represent an instant in time. + */ +typedef int64_t TimePrivate; + +}} // namespace qpid::sys + +#endif /*!QPID_SYS_POSIX_TIME_H*/ diff --git a/qpid/cpp/include/qpid/sys/posix/check.h b/qpid/cpp/include/qpid/sys/posix/check.h new file mode 100644 index 0000000000..1bfe5d6d78 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/posix/check.h @@ -0,0 +1,53 @@ +#ifndef _posix_check_h +#define _posix_check_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" +#include "qpid/Msg.h" + +#include <cerrno> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +#define QPID_POSIX_ERROR(ERRNO) qpid::Exception(QPID_MSG(qpid::sys::strError(ERRNO))) + +/** THROW QPID_POSIX_ERROR(errno) if RESULT is less than zero */ +#define QPID_POSIX_CHECK(RESULT) \ + if ((RESULT) < 0) throw QPID_POSIX_ERROR((errno)) + +/** Throw a posix error if ERRNO is non-zero */ +#define QPID_POSIX_THROW_IF(ERRNO) \ + do { int e=(ERRNO); if (e) throw QPID_POSIX_ERROR(e); } while(0) + +/** Same as _THROW_IF in a release build, but abort a debug build */ +#ifdef NDEBUG +#define QPID_POSIX_ASSERT_THROW_IF(ERRNO) QPID_POSIX_THROW_IF(ERRNO) +#else +#define QPID_POSIX_ASSERT_THROW_IF(ERRNO) \ + do { int e=(ERRNO); if (e) { errno=e; ::perror(0); assert(0); } } while(0) +#endif + +#define QPID_POSIX_ABORT_IF(ERRNO) if ((int) ERRNO) { errno=ERRNO; ::perror(0); abort(); } + +#endif /*!_posix_check_h*/ diff --git a/qpid/cpp/include/qpid/sys/windows/Condition.h b/qpid/cpp/include/qpid/sys/windows/Condition.h new file mode 100755 index 0000000000..cd5aebbf09 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/windows/Condition.h @@ -0,0 +1,77 @@ +#ifndef _sys_windows_Condition_h +#define _sys_windows_Condition_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/Mutex.h" +#include "qpid/sys/Time.h" + +#include <time.h> +#include <boost/noncopyable.hpp> +#include <boost/thread/condition.hpp> +#include <boost/thread/thread_time.hpp> +#include <windows.h> + +namespace qpid { +namespace sys { + +/** + * A condition variable for thread synchronization. + */ +class Condition : private boost::noncopyable +{ + public: + inline Condition(); + inline ~Condition(); + inline void wait(Mutex&); + inline bool wait(Mutex&, const AbsTime& absoluteTime); + inline void notify(); + inline void notifyAll(); + + private: + boost::condition_variable_any condition; +}; + +Condition::Condition() { +} + +Condition::~Condition() { +} + +void Condition::wait(Mutex& mutex) { + condition.wait(mutex.mutex); +} + +bool Condition::wait(Mutex& mutex, const AbsTime& absoluteTime){ + return condition.timed_wait(mutex.mutex, absoluteTime.timepoint); +} + +void Condition::notify(){ + condition.notify_one(); +} + +void Condition::notifyAll(){ + condition.notify_all(); +} + +}} +#endif /*!_sys_windows_Condition_h*/ diff --git a/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h b/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h new file mode 100755 index 0000000000..fff320bc96 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h @@ -0,0 +1,40 @@ +#ifndef QPID_SYS_WINDOWS_INTEGERTYPES_H +#define QPID_SYS_WINDOWS_INTEGERTYPES_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. + * + */ + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +#if defined(_MSC_VER) +typedef char int8_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#else +#include <stdint.h> +#endif + +// Visual Studio doesn't define other common types, so set them up here too. +typedef unsigned int uint; + +#endif /*!QPID_SYS_WINDOWS_INTEGERTYPES_H*/ diff --git a/qpid/cpp/include/qpid/sys/windows/Mutex.h b/qpid/cpp/include/qpid/sys/windows/Mutex.h new file mode 100755 index 0000000000..5dcc69e836 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/windows/Mutex.h @@ -0,0 +1,188 @@ +#ifndef _sys_windows_Mutex_h +#define _sys_windows_Mutex_h + +/* + * + * Copyright (c) 2008 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/windows/check.h" + +#include <boost/version.hpp> +#if (BOOST_VERSION < 103500) +#error The Windows port requires Boost version 1.35.0 or later +#endif + +#include <boost/noncopyable.hpp> +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread_time.hpp> +#include <boost/thread/tss.hpp> + +namespace qpid { +namespace sys { + +class Condition; + +/** + * Mutex lock. + */ +class Mutex : private boost::noncopyable { + friend class Condition; + +public: + typedef ::qpid::sys::ScopedLock<Mutex> ScopedLock; + typedef ::qpid::sys::ScopedUnlock<Mutex> ScopedUnlock; + + inline Mutex(); + inline ~Mutex(); + inline void lock(); + inline void unlock(); + inline bool trylock(); + + +protected: + boost::recursive_mutex mutex; +}; + +/** + * RW lock. + */ +class RWlock : private boost::noncopyable { + friend class Condition; + +public: + typedef ::qpid::sys::ScopedRlock<RWlock> ScopedRlock; + typedef ::qpid::sys::ScopedWlock<RWlock> ScopedWlock; + + inline RWlock(); + inline ~RWlock(); + inline void wlock(); // will write-lock + inline void rlock(); // will read-lock + inline void unlock(); + inline void trywlock(); // will write-try + inline void tryrlock(); // will read-try + +protected: + boost::shared_mutex rwMutex; + boost::thread_specific_ptr<bool> haveWrite; + + inline bool &write (void); +}; + + +/** + * PODMutex is a POD, can be static-initialized with + * PODMutex m = QPID_PODMUTEX_INITIALIZER + */ +struct PODMutex +{ + typedef ::qpid::sys::ScopedLock<PODMutex> ScopedLock; + + inline void lock(); + inline void unlock(); + inline bool trylock(); + + // Must be public to be a POD: + boost::recursive_mutex mutex; +}; + +#define QPID_MUTEX_INITIALIZER 0 + +void PODMutex::lock() { + mutex.lock(); +} + +void PODMutex::unlock() { + mutex.unlock(); +} + +bool PODMutex::trylock() { + return mutex.try_lock(); +} + +Mutex::Mutex() { +} + +Mutex::~Mutex(){ +} + +void Mutex::lock() { + mutex.lock(); +} + +void Mutex::unlock() { + mutex.unlock(); +} + +bool Mutex::trylock() { + return mutex.try_lock(); +} + + +RWlock::RWlock() { +} + +RWlock::~RWlock(){ +} + +void RWlock::wlock() { + bool &writer = write(); + rwMutex.lock(); + writer = true; // Remember this thread has write lock held. +} + +void RWlock::rlock() { + bool &writer = write(); + rwMutex.lock_shared(); + writer = false; // Remember this thread has shared lock held. +} + +void RWlock::unlock() { + bool &writer = write(); + if (writer) + rwMutex.unlock(); + else + rwMutex.unlock_shared(); +} + +void RWlock::trywlock() { + bool &writer = write(); + // shared_mutex::try_lock() seems to not be available... emulate it with + // a timed lock(). + boost::system_time now = boost::get_system_time(); + if (rwMutex.timed_lock(now)) + writer = true; +} + +void RWlock::tryrlock() { + bool &writer = write(); + if (rwMutex.try_lock_shared()) + writer = false; +} + +bool & RWlock::write (void) { + // Accessing thread-specific and stack-local info, so no locks needed. + bool *writePtr = haveWrite.get(); + if (writePtr == 0) { + writePtr = new bool(false); + haveWrite.reset(writePtr); + } + return *writePtr; +} + +}} +#endif /*!_sys_windows_Mutex_h*/ diff --git a/qpid/cpp/include/qpid/sys/windows/Time.h b/qpid/cpp/include/qpid/sys/windows/Time.h new file mode 100644 index 0000000000..2987b1c8b2 --- /dev/null +++ b/qpid/cpp/include/qpid/sys/windows/Time.h @@ -0,0 +1,36 @@ +#ifndef QPID_SYS_WINDOWS_TIME_H +#define QPID_SYS_WINDOWS_TIME_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 <boost/date_time/posix_time/posix_time_types.hpp> + +namespace qpid { +namespace sys { + +/** + * Class to represent an instant in time. Boost has this stuff already done + * so just reuse it. We can also grab this for quick use with the Condition + * wait operations. + */ +typedef boost::posix_time::ptime TimePrivate; + +}} // namespace qpid::sys + +#endif /*!QPID_SYS_WINDOWS_TIME_H*/ diff --git a/qpid/cpp/include/qpid/sys/windows/check.h b/qpid/cpp/include/qpid/sys/windows/check.h new file mode 100755 index 0000000000..2a8e439bed --- /dev/null +++ b/qpid/cpp/include/qpid/sys/windows/check.h @@ -0,0 +1,49 @@ +#ifndef _windows_check_h +#define _windows_check_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" +#include "qpid/Msg.h" +#include "qpid/sys/StrError.h" + +#define QPID_WINDOWS_ERROR(ERRVAL) qpid::Exception(QPID_MSG(qpid::sys::strError(ERRVAL))) +#define QPID_WINDOWS_CRT_ERROR(ERRNO) qpid::Exception(QPID_MSG(qpid::sys::strError(ERRNO))) + +/** THROW QPID_WINDOWS_ERROR(::GetLastError()) if RESULT is NULL */ +#define QPID_WINDOWS_CHECK_NULL(RESULT) \ + if ((RESULT) == NULL) throw QPID_WINDOWS_ERROR((::GetLastError())) + +#define QPID_WINDOWS_CHECK_NOT(RESULT,VAL) \ + if ((RESULT) == (VAL)) throw QPID_WINDOWS_ERROR((::GetLastError())) + +#define QPID_WINDOWS_CHECK_ASYNC_START(STATUS) \ + if (!(STATUS) && ::WSAGetLastError() != ERROR_IO_PENDING) \ + throw QPID_WINDOWS_ERROR((::WSAGetLastError())) + +#define QPID_WINDOWS_CHECK_CRT_NZ(VAL) \ + if ((VAL) == 0) throw QPID_WINDOWS_CRT_ERROR(errno) + +#define QPID_WINSOCK_CHECK(OP) \ + if ((OP) == SOCKET_ERROR) throw QPID_WINDOWS_ERROR((::WSAGetLastError())) + +#endif /*!_windows_check_h*/ diff --git a/qpid/cpp/include/qpid/types/Exception.h b/qpid/cpp/include/qpid/types/Exception.h new file mode 100644 index 0000000000..483d104cc8 --- /dev/null +++ b/qpid/cpp/include/qpid/types/Exception.h @@ -0,0 +1,44 @@ +#ifndef QPID_TYPES_EXCEPTION_H +#define QPID_TYPES_EXCEPTION_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/types/ImportExport.h" + +namespace qpid { +namespace types { + +class QPID_TYPES_CLASS_EXTERN Exception : public std::exception +{ + public: + QPID_TYPES_EXTERN explicit Exception(const std::string& message=std::string()) throw(); + QPID_TYPES_EXTERN virtual ~Exception() throw(); + QPID_TYPES_EXTERN virtual const char* what() const throw(); + + private: + const std::string message; +}; + +}} // namespace qpid::types + +#endif /*!QPID_TYPES_EXCEPTION_H*/ diff --git a/qpid/cpp/include/qpid/types/ImportExport.h b/qpid/cpp/include/qpid/types/ImportExport.h new file mode 100644 index 0000000000..8fa41884fb --- /dev/null +++ b/qpid/cpp/include/qpid/types/ImportExport.h @@ -0,0 +1,35 @@ +#ifndef QPID_TYPES_IMPORTEXPORT_H +#define QPID_TYPES_IMPORTEXPORT_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/ImportExport.h" + +#if defined(TYPES_EXPORT) || defined (qpidtypes_EXPORTS) +# define QPID_TYPES_EXTERN QPID_EXPORT +# define QPID_TYPES_CLASS_EXTERN QPID_CLASS_EXPORT +# define QPID_TYPES_INLINE_EXTERN QPID_INLINE_EXPORT +#else +# define QPID_TYPES_EXTERN QPID_IMPORT +# define QPID_TYPES_CLASS_EXTERN QPID_CLASS_IMPORT +# define QPID_TYPES_INLINE_EXTERN QPID_INLINE_IMPORT +#endif + +#endif /*!QPID_TYPES_IMPORTEXPORT_H*/ diff --git a/qpid/cpp/include/qpid/types/Uuid.h b/qpid/cpp/include/qpid/types/Uuid.h new file mode 100644 index 0000000000..02af4c7e7f --- /dev/null +++ b/qpid/cpp/include/qpid/types/Uuid.h @@ -0,0 +1,94 @@ +#ifndef QPID_TYPES_UUID_H +#define QPID_TYPES_UUID_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/types/ImportExport.h" +#include <iosfwd> +#include <string> + +namespace qpid { +namespace types { + +class QPID_TYPES_CLASS_EXTERN Uuid +{ + public: + static const size_t SIZE; + /** + * If unique is true, this will generate a new unique uuid, if not + * it will construct a null uuid. + */ + QPID_TYPES_EXTERN Uuid(bool unique=false); + QPID_TYPES_EXTERN Uuid(const Uuid&); + QPID_TYPES_EXTERN Uuid& operator=(const Uuid&); + /** Copy the UUID from data16, which must point to a 16-byte UUID */ + QPID_TYPES_EXTERN Uuid(const unsigned char* data16); + + /** Set to a new unique identifier. */ + QPID_TYPES_EXTERN void generate(); + + /** Set to all zeros. */ + QPID_TYPES_EXTERN void clear(); + + /** Test for null (all zeros). */ + QPID_TYPES_EXTERN bool isNull() const; + QPID_TYPES_EXTERN operator bool() const; + QPID_TYPES_EXTERN bool operator!() const; + + /** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ + QPID_TYPES_EXTERN std::string str() const; + + QPID_TYPES_EXTERN size_t size() const; + QPID_TYPES_EXTERN const unsigned char* data() const; + + friend QPID_TYPES_EXTERN bool operator==(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator!=(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator<(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator>(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator<=(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN bool operator>=(const Uuid&, const Uuid&); + friend QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream&, Uuid); + friend QPID_TYPES_EXTERN std::istream& operator>>(std::istream&, Uuid&); + + private: + unsigned char bytes[16]; +}; + +/** Returns true if the uuids are equal, false otherwise. **/ +QPID_TYPES_EXTERN bool operator==(const Uuid&, const Uuid&); +/** Returns true if the uuids are NOT equal, false if they are. **/ +QPID_TYPES_EXTERN bool operator!=(const Uuid&, const Uuid&); + +QPID_TYPES_EXTERN bool operator<(const Uuid&, const Uuid&); +QPID_TYPES_EXTERN bool operator>(const Uuid&, const Uuid&); +QPID_TYPES_EXTERN bool operator<=(const Uuid&, const Uuid&); +QPID_TYPES_EXTERN bool operator>=(const Uuid&, const Uuid&); + +/** Print in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream&, Uuid); + +/** Read from format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */ +QPID_TYPES_EXTERN std::istream& operator>>(std::istream&, Uuid&); + +}} // namespace qpid::types + +#endif /*!QPID_TYPES_UUID_H*/ diff --git a/qpid/cpp/include/qpid/types/Variant.h b/qpid/cpp/include/qpid/types/Variant.h new file mode 100644 index 0000000000..4459fc4123 --- /dev/null +++ b/qpid/cpp/include/qpid/types/Variant.h @@ -0,0 +1,181 @@ +#ifndef QPID_TYPES_VARIANT_H +#define QPID_TYPES_VARIANT_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 <list> +#include <map> +#include <ostream> +#include <string> +#include "Uuid.h" +#include "qpid/types/Exception.h" +#include "qpid/sys/IntegerTypes.h" +#include "qpid/types/ImportExport.h" + +namespace qpid { +namespace types { + +/** + * Thrown when an illegal conversion of a variant is attempted. + */ +struct QPID_TYPES_CLASS_EXTERN InvalidConversion : public Exception +{ + InvalidConversion(const std::string& msg); +}; + +enum VariantType { + VAR_VOID = 0, + VAR_BOOL, + VAR_UINT8, + VAR_UINT16, + VAR_UINT32, + VAR_UINT64, + VAR_INT8, + VAR_INT16, + VAR_INT32, + VAR_INT64, + VAR_FLOAT, + VAR_DOUBLE, + VAR_STRING, + VAR_MAP, + VAR_LIST, + VAR_UUID +}; + +std::string getTypeName(VariantType type); + +class VariantImpl; + +/** + * Represents a value of variable type. + */ +class QPID_TYPES_CLASS_EXTERN Variant +{ + public: + typedef std::map<std::string, Variant> Map; + typedef std::list<Variant> List; + + QPID_TYPES_EXTERN Variant(); + QPID_TYPES_EXTERN Variant(bool); + QPID_TYPES_EXTERN Variant(uint8_t); + QPID_TYPES_EXTERN Variant(uint16_t); + QPID_TYPES_EXTERN Variant(uint32_t); + QPID_TYPES_EXTERN Variant(uint64_t); + QPID_TYPES_EXTERN Variant(int8_t); + QPID_TYPES_EXTERN Variant(int16_t); + QPID_TYPES_EXTERN Variant(int32_t); + QPID_TYPES_EXTERN Variant(int64_t); + QPID_TYPES_EXTERN Variant(float); + QPID_TYPES_EXTERN Variant(double); + QPID_TYPES_EXTERN Variant(const std::string&); + QPID_TYPES_EXTERN Variant(const char*); + QPID_TYPES_EXTERN Variant(const Map&); + QPID_TYPES_EXTERN Variant(const List&); + QPID_TYPES_EXTERN Variant(const Variant&); + QPID_TYPES_EXTERN Variant(const Uuid&); + + QPID_TYPES_EXTERN ~Variant(); + + QPID_TYPES_EXTERN VariantType getType() const; + QPID_TYPES_EXTERN bool isVoid() const; + + QPID_TYPES_EXTERN Variant& operator=(bool); + QPID_TYPES_EXTERN Variant& operator=(uint8_t); + QPID_TYPES_EXTERN Variant& operator=(uint16_t); + QPID_TYPES_EXTERN Variant& operator=(uint32_t); + QPID_TYPES_EXTERN Variant& operator=(uint64_t); + QPID_TYPES_EXTERN Variant& operator=(int8_t); + QPID_TYPES_EXTERN Variant& operator=(int16_t); + QPID_TYPES_EXTERN Variant& operator=(int32_t); + QPID_TYPES_EXTERN Variant& operator=(int64_t); + QPID_TYPES_EXTERN Variant& operator=(float); + QPID_TYPES_EXTERN Variant& operator=(double); + QPID_TYPES_EXTERN Variant& operator=(const std::string&); + QPID_TYPES_EXTERN Variant& operator=(const char*); + QPID_TYPES_EXTERN Variant& operator=(const Map&); + QPID_TYPES_EXTERN Variant& operator=(const List&); + QPID_TYPES_EXTERN Variant& operator=(const Variant&); + QPID_TYPES_EXTERN Variant& operator=(const Uuid&); + + /** + * Parses the argument and assigns itself the appropriate + * value. Recognises integers, doubles and booleans. + */ + QPID_TYPES_EXTERN Variant& parse(const std::string&); + + QPID_TYPES_EXTERN bool asBool() const; + QPID_TYPES_EXTERN uint8_t asUint8() const; + QPID_TYPES_EXTERN uint16_t asUint16() const; + QPID_TYPES_EXTERN uint32_t asUint32() const; + QPID_TYPES_EXTERN uint64_t asUint64() const; + QPID_TYPES_EXTERN int8_t asInt8() const; + QPID_TYPES_EXTERN int16_t asInt16() const; + QPID_TYPES_EXTERN int32_t asInt32() const; + QPID_TYPES_EXTERN int64_t asInt64() const; + QPID_TYPES_EXTERN float asFloat() const; + QPID_TYPES_EXTERN double asDouble() const; + QPID_TYPES_EXTERN std::string asString() const; + QPID_TYPES_EXTERN Uuid asUuid() const; + + QPID_TYPES_EXTERN operator bool() const; + QPID_TYPES_EXTERN operator uint8_t() const; + QPID_TYPES_EXTERN operator uint16_t() const; + QPID_TYPES_EXTERN operator uint32_t() const; + QPID_TYPES_EXTERN operator uint64_t() const; + QPID_TYPES_EXTERN operator int8_t() const; + QPID_TYPES_EXTERN operator int16_t() const; + QPID_TYPES_EXTERN operator int32_t() const; + QPID_TYPES_EXTERN operator int64_t() const; + QPID_TYPES_EXTERN operator float() const; + QPID_TYPES_EXTERN operator double() const; + QPID_TYPES_EXTERN operator std::string() const; + QPID_TYPES_EXTERN operator Uuid() const; + + QPID_TYPES_EXTERN const Map& asMap() const; + QPID_TYPES_EXTERN Map& asMap(); + QPID_TYPES_EXTERN const List& asList() const; + QPID_TYPES_EXTERN List& asList(); + /** + * Unlike asString(), getString() will not do any conversions and + * will throw InvalidConversion if the type is not STRING. + */ + QPID_TYPES_EXTERN const std::string& getString() const; + QPID_TYPES_EXTERN std::string& getString(); + + QPID_TYPES_EXTERN void setEncoding(const std::string&); + QPID_TYPES_EXTERN const std::string& getEncoding() const; + + QPID_TYPES_EXTERN bool isEqualTo(const Variant& a) const; + + QPID_TYPES_EXTERN void reset(); + private: + VariantImpl* impl; +}; + +#ifndef SWIG +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream& out, const Variant& value); +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream& out, const Variant::Map& map); +QPID_TYPES_EXTERN std::ostream& operator<<(std::ostream& out, const Variant::List& list); +QPID_TYPES_EXTERN bool operator==(const Variant& a, const Variant& b); +#endif +}} // namespace qpid::types + +#endif /*!QPID_TYPES_VARIANT_H*/ |