[seiscomp, scanloc] Install, add .gitignore
This commit is contained in:
314
include/seiscomp/messaging/connection.h
Normal file
314
include/seiscomp/messaging/connection.h
Normal file
@ -0,0 +1,314 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_CLIENT_CONNECTION_H
|
||||
#define SEISCOMP_CLIENT_CONNECTION_H
|
||||
|
||||
|
||||
#include <seiscomp/core/message.h>
|
||||
#include <seiscomp/messaging/protocol.h>
|
||||
#include <seiscomp/utils/timer.h>
|
||||
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
namespace Client {
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(Connection);
|
||||
|
||||
/**
|
||||
* @brief The Connection class implements the high level connection to a
|
||||
* messaging backend. It requires a protocol implementation and
|
||||
* parses the message from the wire into an object tree.
|
||||
*
|
||||
* @code
|
||||
* ConnectionPtr c = new Connection;
|
||||
* if ( c->setSource("scmp://app@localhost/testing") != OK ) {
|
||||
* cerr << "Invalid source" <<endl;
|
||||
* exit(1);
|
||||
* }
|
||||
*
|
||||
* if ( c->connect() != OK ) {
|
||||
* cerr << "Could not open connection" <<endl;
|
||||
* exit(1);
|
||||
* }
|
||||
*
|
||||
* cout << "Connected as " << c->clientName() << endl;
|
||||
* Message *nmsg;
|
||||
* while ( msg = c->receive(&nmsg) ) {
|
||||
* cout << "Received message from " << nmsg->sender << endl;
|
||||
* }
|
||||
*
|
||||
* c->close();
|
||||
* @endcode
|
||||
*/
|
||||
class SC_SYSTEM_CLIENT_API Connection : public Core::BaseObject {
|
||||
public:
|
||||
typedef std::list<Connection*> Connections;
|
||||
typedef std::function<void (const Core::Time &, std::ostream&)> InfoCallback;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// X'truction
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
//! C'tor
|
||||
Connection(Protocol *proto = nullptr);
|
||||
//! D'tor
|
||||
~Connection();
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Public interface
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
/**
|
||||
* @brief Sets the default content encoding passed to the final
|
||||
* implementation of \ref Protocol.sendMessage.
|
||||
*
|
||||
* This is taken as a hint and implementations can or cannot respect
|
||||
* it. The default encoding is deflate.
|
||||
*
|
||||
* @param enc The content encoding
|
||||
*/
|
||||
void setContentEncoding(Protocol::ContentEncoding enc);
|
||||
|
||||
/**
|
||||
* @brief Sets the default content type passed to the final
|
||||
* implementation of \ref Protocol.sendMessage.
|
||||
*
|
||||
* This is taken as a hint and implementations can or cannot respect
|
||||
* it. The default type is binary.
|
||||
*
|
||||
* @param type The content type
|
||||
*/
|
||||
void setContentType(Protocol::ContentType type);
|
||||
|
||||
/**
|
||||
* @brief Creates a connection to the given URL.
|
||||
*
|
||||
* The protocol implementation is created from the given protocol.
|
||||
* The default is 'scmp' and can be omitted: 'localhost/testing' and
|
||||
* 'scmp://localhost/testing' are equal.
|
||||
* If a username is passed then it will be required for registration
|
||||
* otherwise a random username (clientname) will be created and
|
||||
* assigned to the connection.
|
||||
*
|
||||
* Only the protocol implementation will be instantiated and the
|
||||
* address will be saved. A real connection attempt isn't being
|
||||
* made at this point.
|
||||
*
|
||||
* If a protocol has been set already in the constructor then it will
|
||||
* be used if the protocol is omitted in the URL. Otherwise it will be
|
||||
* replaced by the given protocol.
|
||||
*
|
||||
* @param url The URL in format proto://user@host/queue
|
||||
* @return An unmanaged connection pointer or nullptr in case of error.
|
||||
*/
|
||||
Result setSource(const char *URL);
|
||||
Result setSource(const std::string &URL);
|
||||
|
||||
//! Returns the configured source
|
||||
const std::string &source() const;
|
||||
|
||||
/**
|
||||
* @brief Sets whether membership info of clients should be received.
|
||||
* This information informs about when another client enters
|
||||
* one of the groups this connection is subscribed to, when
|
||||
* another clients leaves one of the groups this connection is
|
||||
* subscribed to and when a client disconnects from the
|
||||
* broker.
|
||||
* This method has to be called prior to connect and after
|
||||
* setSource to have an affect.
|
||||
* @param enable true if membership info should be received, false
|
||||
* otherwise.
|
||||
*/
|
||||
Result setMembershipInfo(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Attempts to connect to the messaging backend located at the
|
||||
* given source (@setSource).
|
||||
* @param clientName An optional clientname.
|
||||
* @param primaryGroup The primary messaging group. If empty then the
|
||||
* connection is treated as read-only connection.
|
||||
* @param timeoutMs The handshake timeout in milliseconds. If zero then
|
||||
* no timeout is being used.
|
||||
* @return Result code
|
||||
*/
|
||||
Result connect(const std::string &clientName,
|
||||
const std::string &primaryGroup,
|
||||
unsigned int timeoutMs = 3000);
|
||||
|
||||
//! Disconnects from the backend
|
||||
Result disconnect();
|
||||
|
||||
//! Returns whether a connection is established or not
|
||||
bool isConnected() const;
|
||||
|
||||
/**
|
||||
* @brief Reconnects the last established connection.
|
||||
*
|
||||
* If the connection is still established then it will disconnect
|
||||
* first.
|
||||
*
|
||||
* @return Result code
|
||||
*/
|
||||
Result reconnect();
|
||||
|
||||
//! Closes the connection to the backend the hard way
|
||||
Result close();
|
||||
|
||||
/**
|
||||
* @brief Sets the read timeout for receiving a message. If the
|
||||
* timeout hits then TimeoutError is returned.
|
||||
* @param milliseconds The timeout in milliseconds. Zero or a negative
|
||||
* value disabled the timeout.
|
||||
* @return Result code
|
||||
*/
|
||||
Result setTimeout(int milliseconds);
|
||||
|
||||
Result subscribe(const char *group);
|
||||
Result subscribe(const std::string &group);
|
||||
Result unsubscribe(const char *group);
|
||||
Result unsubscribe(const std::string &group);
|
||||
|
||||
/**
|
||||
* @brief Waits for a new message to arrive so that a subsequent call
|
||||
* to \ref recv() will return immediately.
|
||||
* @return Result code
|
||||
*/
|
||||
Result fetchInbox();
|
||||
|
||||
/**
|
||||
* @brief Synchronizes the outbox with the remote server.
|
||||
* See Protocol::syncOutbox().
|
||||
* @return Result code
|
||||
*/
|
||||
Result syncOutbox();
|
||||
|
||||
/**
|
||||
* @brief Reads a message from the backend. If no message is available
|
||||
* locally the call will block until a message arrives.
|
||||
* @param packet An optional storage pointer to the transmitted packet
|
||||
* from which the message has been created. The ownership
|
||||
* goes to the caller.
|
||||
* @param status An optional status storage which holds the result of
|
||||
* the operation.
|
||||
* @return The message pointer. nullptr is returned if either an error
|
||||
* occurred or a system packet was received. This requires a
|
||||
* package storage pointer to be passed.
|
||||
*/
|
||||
Core::Message *recv(Packet **packet = nullptr, Result *status = nullptr);
|
||||
Core::Message *recv(PacketPtr &packet, Result *status = nullptr);
|
||||
|
||||
Result sendMessage(const Core::Message *msg);
|
||||
Result sendMessage(const std::string &targetGroup, const Core::Message *msg);
|
||||
|
||||
//! The following three functions are actually convenience wrapper for
|
||||
//! backward compatibility
|
||||
bool send(const Core::Message *msg);
|
||||
bool send(const std::string &targetGroup, const Core::Message *msg);
|
||||
|
||||
size_t inboxSize() const;
|
||||
|
||||
const Protocol::State *state() const;
|
||||
|
||||
Result lastError() const;
|
||||
const std::string lastErrorMessage() const;
|
||||
|
||||
Protocol *protocol() const;
|
||||
|
||||
void setInfoCallback(InfoCallback);
|
||||
|
||||
void getInfo(const Core::Time ×tamp, std::ostream &os);
|
||||
|
||||
Result setCertificate(const std::string &cert);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Query functions
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
/**
|
||||
* @brief Returns the client name. Either the one given during connect
|
||||
* or the one assigned by the server.
|
||||
* @return The client name
|
||||
*/
|
||||
const std::string &clientName() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the schema version supported by the remote end.
|
||||
* This requires a successfull connection to be valid.
|
||||
* @return The version of the remote schema
|
||||
*/
|
||||
Core::Version schemaVersion() const;
|
||||
|
||||
// See Protocoll::configurationParameters
|
||||
const Protocol::KeyValueStore *extendedParameters() const;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Protected interface
|
||||
// ----------------------------------------------------------------------
|
||||
protected:
|
||||
static void registerConnection(Connection *con);
|
||||
static void unregisterConnection(Connection *con);
|
||||
|
||||
|
||||
protected:
|
||||
ProtocolPtr _protocol;
|
||||
Protocol::ContentEncoding _defaultContentEncoding;
|
||||
Protocol::ContentType _defaultContentType;
|
||||
std::string _address;
|
||||
std::string _clientName;
|
||||
std::string _primaryGroup;
|
||||
unsigned int _timeoutMs;
|
||||
Result _lastError;
|
||||
InfoCallback _infoCallback;
|
||||
Connections::iterator _poolIterator;
|
||||
};
|
||||
|
||||
|
||||
inline Result Connection::lastError() const {
|
||||
return _lastError;
|
||||
}
|
||||
|
||||
inline const std::string &Connection::source() const {
|
||||
return _address;
|
||||
}
|
||||
|
||||
inline bool Connection::send(const Core::Message *msg) {
|
||||
return sendMessage(msg) == OK;
|
||||
}
|
||||
|
||||
inline bool Connection::send(const std::string &targetGroup, const Core::Message *msg) {
|
||||
return sendMessage(targetGroup, msg) == OK;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
120
include/seiscomp/messaging/messages/database.h
Normal file
120
include/seiscomp/messaging/messages/database.h
Normal file
@ -0,0 +1,120 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_CLIENT_DATABASEMESSAGE_H
|
||||
#define SEISCOMP_CLIENT_DATABASEMESSAGE_H
|
||||
|
||||
|
||||
#include <seiscomp/messaging/messages/service.h>
|
||||
#include <seiscomp/io/database.h>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
|
||||
// Forward declarations
|
||||
namespace IO {
|
||||
|
||||
class DatabaseInterface;
|
||||
|
||||
}
|
||||
|
||||
namespace Client {
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(DatabaseRequestMessage);
|
||||
|
||||
/**
|
||||
* \brief Message for requesting a database service
|
||||
* This message type requests a databaseservice.
|
||||
* The servicename is optional. If the servicename is not
|
||||
* given the serviceprovider can choose between different
|
||||
* services it offers of this type.
|
||||
* So if the provider offers a mysql database and a postgresql
|
||||
* database it can select the published service by its own.
|
||||
* If the servicename is set the provider has to publish
|
||||
* the service matching this name if it is able to do so.
|
||||
*/
|
||||
class SC_SYSTEM_CLIENT_API DatabaseRequestMessage : public ServiceRequestMessage {
|
||||
DECLARE_SC_CLASS(DatabaseRequestMessage)
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
DatabaseRequestMessage();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param service The requested service name.
|
||||
* The name can be set nullptr to let the
|
||||
* service request handler decide which
|
||||
* interface it will return.
|
||||
*/
|
||||
DatabaseRequestMessage(const char *service);
|
||||
};
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(DatabaseProvideMessage);
|
||||
|
||||
/**
|
||||
* \brief Message for providing a database service
|
||||
* When receiving this message a corresponding databaseinterface
|
||||
* can be created which one connects to using the provided
|
||||
* parameters.
|
||||
* \code
|
||||
* DatabaseProvideMessagePtr msg = DatabaseProvideMessage_Cast(con->read());
|
||||
* Seiscomp::IO::DatabaseInterfacePtr db = msg->interface();
|
||||
* if ( db != nullptr ) {
|
||||
* // do fancy things with the interface
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
class SC_SYSTEM_CLIENT_API DatabaseProvideMessage : public ServiceProvideMessage {
|
||||
DECLARE_SC_CLASS(DatabaseProvideMessage)
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
DatabaseProvideMessage();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param service The provided service name.
|
||||
* @param params The connection parameters.
|
||||
*/
|
||||
DatabaseProvideMessage(const char *service,
|
||||
const char *params);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns a database interface for the provided service
|
||||
* which is already connected to the database.
|
||||
* @return The connected database interface. nullptr, if the
|
||||
* databaseinterface cannot be created or if the
|
||||
* connection fails.
|
||||
* NOTE: The caller is reponsible for deleting the
|
||||
* returned object.
|
||||
*/
|
||||
IO::DatabaseInterface *database() const;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
122
include/seiscomp/messaging/messages/service.h
Normal file
122
include/seiscomp/messaging/messages/service.h
Normal file
@ -0,0 +1,122 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_MESSAGING_MESSAGES_DATABASE_H
|
||||
#define SEISCOMP_MESSAGING_MESSAGES_DATABASE_H
|
||||
|
||||
|
||||
#include <seiscomp/core/message.h>
|
||||
#include <seiscomp/client.h>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
namespace Client {
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(ServiceRequestMessage);
|
||||
|
||||
/**
|
||||
* \brief Message for requesting a service
|
||||
* This class is the base class for all kinds of service
|
||||
* requests being sent over the network.
|
||||
* It holds an optional servicename. If the servicename
|
||||
* is not set the request handler can choose a service
|
||||
* matching the servicetype defined by the classname.
|
||||
* A message of this type cannot not be sent. One has to
|
||||
* derive a class to define the type of service (database,
|
||||
* fileaccess, ...).
|
||||
*/
|
||||
class SC_SYSTEM_CLIENT_API ServiceRequestMessage : public Core::Message {
|
||||
DECLARE_SC_CLASS(ServiceRequestMessage)
|
||||
DECLARE_SERIALIZATION;
|
||||
|
||||
protected:
|
||||
//! Constructor
|
||||
ServiceRequestMessage();
|
||||
|
||||
/**
|
||||
* C'tor
|
||||
* @param service The requested service name.
|
||||
* The name can be set nullptr to let the
|
||||
* service request handler decide which
|
||||
* interface it will return.
|
||||
*/
|
||||
ServiceRequestMessage(const char *service);
|
||||
|
||||
//! Implemented interface from Message
|
||||
bool empty() const override;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @return The requested service name
|
||||
*/
|
||||
const char* service() const;
|
||||
|
||||
private:
|
||||
std::string _serviceName;
|
||||
};
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(ServiceProvideMessage);
|
||||
|
||||
/**
|
||||
* \brief Message for providing a service
|
||||
* This class is the base class for all kinds of service
|
||||
* providers.
|
||||
* It holds a servicename and the connection parameters.
|
||||
*/
|
||||
class SC_SYSTEM_CLIENT_API ServiceProvideMessage : public Seiscomp::Core::Message {
|
||||
DECLARE_SC_CLASS(ServiceProvideMessage)
|
||||
DECLARE_SERIALIZATION;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor
|
||||
* @param service The provided service name.
|
||||
* @param params The connection parameters.
|
||||
*/
|
||||
ServiceProvideMessage(const char *service,
|
||||
const char *params);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @return The provided service name.
|
||||
*/
|
||||
const char *service() const;
|
||||
|
||||
/**
|
||||
* @return The connection parameters.
|
||||
*/
|
||||
const char *parameters() const;
|
||||
|
||||
//! Implemented interface from Message
|
||||
virtual bool empty() const;
|
||||
|
||||
private:
|
||||
std::string _serviceName;
|
||||
std::string _parameters;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
89
include/seiscomp/messaging/packet.h
Normal file
89
include/seiscomp/messaging/packet.h
Normal file
@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_CLIENT_PACKET_H
|
||||
#define SEISCOMP_CLIENT_PACKET_H
|
||||
|
||||
|
||||
#include <seiscomp/core/message.h>
|
||||
#include <seiscomp/client.h>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
namespace Client {
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(Packet);
|
||||
|
||||
/**
|
||||
* @brief The Packet struct provides access to a data packet received
|
||||
* from a messaging backend.
|
||||
*
|
||||
* Apart from metadata a package only contains a vector of octetts which
|
||||
* are parsed in the next layer. A packet is usually transformed to and
|
||||
* from a message.
|
||||
*/
|
||||
struct SC_SYSTEM_CLIENT_API Packet : Core::BaseObject {
|
||||
DECLARE_CASTS(Packet)
|
||||
|
||||
Packet() : type(Undefined), seqNo(-1) {}
|
||||
|
||||
enum Type {
|
||||
Undefined = -1,
|
||||
Data = 0,
|
||||
Enter = 1,
|
||||
Leave = 2,
|
||||
Status = 3,
|
||||
Disconnected = 4
|
||||
};
|
||||
|
||||
Type type; //!< The message type
|
||||
std::string headerContentEncoding; //!< The encoding raw string
|
||||
std::string headerContentType; //!< The content type raw string
|
||||
std::string sender; //!< The sender's client name
|
||||
std::string target; //!< The target group or peer
|
||||
std::string subject; //!< For ENTER, LEAVE, STATE and DISCONNECTED messages
|
||||
uint64_t seqNo; //!< The optional sequence number
|
||||
std::string payload; //!< The actual payload or *the* message
|
||||
|
||||
Packet &swap(Packet &other);
|
||||
};
|
||||
|
||||
|
||||
inline Packet &Packet::swap(Packet &other) {
|
||||
std::swap(type, other.type);
|
||||
sender.swap(other.sender);
|
||||
target.swap(other.target);
|
||||
headerContentEncoding.swap(other.headerContentEncoding);
|
||||
headerContentType.swap(other.headerContentType);
|
||||
subject.swap(other.subject);
|
||||
std::swap(seqNo, other.seqNo);
|
||||
payload.swap(other.payload);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
588
include/seiscomp/messaging/protocol.h
Normal file
588
include/seiscomp/messaging/protocol.h
Normal file
@ -0,0 +1,588 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_CLIENT_PROTOCOL_H
|
||||
#define SEISCOMP_CLIENT_PROTOCOL_H
|
||||
|
||||
|
||||
#include <seiscomp/core/interruptible.h>
|
||||
#include <seiscomp/core/enumeration.h>
|
||||
#include <seiscomp/core/interfacefactory.h>
|
||||
#include <seiscomp/core/optional.h>
|
||||
#include <seiscomp/messaging/packet.h>
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
namespace Client {
|
||||
|
||||
|
||||
PREPAREENUM(Result,
|
||||
EVALUES(
|
||||
/** Everything went find */
|
||||
OK = 0,
|
||||
/** The value/string passed is not an URL */
|
||||
InvalidURL,
|
||||
/** The URL parameters are not correct / not understood */
|
||||
InvalidURLParameters,
|
||||
/** Protocol implementation is not available */
|
||||
InvalidProtocol,
|
||||
/** No content encoding specified e.g. when sending messages */
|
||||
ContentEncodingRequired,
|
||||
/** No content type specified e.g. when sending messages */
|
||||
ContentTypeRequired,
|
||||
/** An unknown content encoding was received */
|
||||
ContentEncodingUnknown,
|
||||
/** An unknown content type was received */
|
||||
ContentTypeUnknown,
|
||||
/** There is already an active connection */
|
||||
AlreadyConnected,
|
||||
/** There is currently no active connection to handle */
|
||||
NotConnected,
|
||||
/** The server closed the connection */
|
||||
ConnectionClosedByPeer,
|
||||
/** A system error, check errno */
|
||||
SystemError,
|
||||
/** The connection timed out */
|
||||
TimeoutError,
|
||||
/** A network error, check errno */
|
||||
NetworkError,
|
||||
/** An application protocol error occurred */
|
||||
NetworkProtocolError,
|
||||
/** The requested username is connected already */
|
||||
DuplicateUsername,
|
||||
/** The remote group does not exist */
|
||||
GroupDoesNotExist,
|
||||
/** There are no inbox messages */
|
||||
InboxUnderflow,
|
||||
/** Too many inbox messages which are not processed */
|
||||
InboxOverflow,
|
||||
/** Too many unacknowledged outbox messages */
|
||||
OutboxOverflow,
|
||||
/** You can't subscribe again to groups you are already subscribed to */
|
||||
AlreadySubscribed,
|
||||
/** You can't unsubscribe from groups you are not subscribed to */
|
||||
NotSubscribed,
|
||||
/** Messages could not be encoded into a packet */
|
||||
EncodingError,
|
||||
/** Package could not be decoded into a message */
|
||||
DecodingError,
|
||||
/** Missing group, e.g. when sending data */
|
||||
MissingGroup,
|
||||
/** Invalid message type enumeration e.g. when sending messages/data */
|
||||
InvalidMessageType,
|
||||
/** Message too large */
|
||||
MessageTooLarge,
|
||||
/** Unspecified error */
|
||||
Error
|
||||
),
|
||||
ENAMES(
|
||||
"OK",
|
||||
"InvalidURL",
|
||||
"InvalidURLParameters",
|
||||
"InvalidProtocol",
|
||||
"ContentEncodingRequired",
|
||||
"ContentTypeRequired",
|
||||
"ContentEncodingUnknown",
|
||||
"ContentTypeUnknown",
|
||||
"AlreadyConnected",
|
||||
"NotConnected",
|
||||
"ConnectionClosedByPeer",
|
||||
"SystemError",
|
||||
"TimeoutError",
|
||||
"NetworkError",
|
||||
"NetworkProtocolError",
|
||||
"DuplicateUsername",
|
||||
"GroupDoesNotExist",
|
||||
"InboxUnderflow",
|
||||
"InboxOverflow",
|
||||
"OutboxOverflow",
|
||||
"AlreadySubscribed",
|
||||
"NotSubscribed",
|
||||
"EncodingError",
|
||||
"DecodingError",
|
||||
"MissingGroup",
|
||||
"InvalidMessageType",
|
||||
"MessageTooLarge",
|
||||
"Error"
|
||||
)
|
||||
);
|
||||
|
||||
class Result : public ENUMWRAPPERCLASS(Result) {
|
||||
public:
|
||||
Result(Type value = Type(0)) : ENUMWRAPPERCLASS(Result)(value) {}
|
||||
Type code() const { return _value; }
|
||||
operator bool() const { return _value == OK; }
|
||||
|
||||
// Disable implicit casts to the enumeration and therefore to
|
||||
// a bool value. A special bool operator is used that maps true to
|
||||
// OK.
|
||||
private:
|
||||
operator Type() const { return ENUMWRAPPERCLASS(Result)::operator Type(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
DEFINE_SMARTPOINTER(Protocol);
|
||||
|
||||
/**
|
||||
* @brief The abstract class Protocol implements the low-level message
|
||||
* transport protocol.
|
||||
*
|
||||
* The protocol handles one connection to a messaging broker and supports
|
||||
* the publish/subscribe pattern. It must implement the methods to subscribe
|
||||
* to a group, unsubscribe from a group and to receive and send messages.
|
||||
* Messages are just binary blobs with associated metadata. The message
|
||||
* content is not interpreted or parsed in any way.
|
||||
*
|
||||
* @code
|
||||
* ProtocolPtr proto = Protocol::Create("scmp");
|
||||
* if ( !proto ) exit(1);
|
||||
* if ( proto->connect("localhost") ) {
|
||||
* cerr << "Connection failed" << endl;
|
||||
* exit(1);
|
||||
* }
|
||||
*
|
||||
* cout << "Connected as " << proto->clientName() << endl;
|
||||
* proto->subscribe("PICK");
|
||||
*
|
||||
* PacketPtr p;
|
||||
* while ( (p = c->recv() ) {
|
||||
* cout << "Packet from " << p->sender() << " to " << p->target << endl;
|
||||
* }
|
||||
*
|
||||
* proto->disconnect();
|
||||
* @endcode
|
||||
*
|
||||
* ## Message Types
|
||||
* ### Regular
|
||||
*
|
||||
* Regular messages will be queued, receive a sequence number and their
|
||||
* content will not be touched by the server unless certain processing
|
||||
* profiles are enabled. That is the default mode of the messaging API.
|
||||
*
|
||||
* ### Transient
|
||||
*
|
||||
* Transient messages are like regular messages but they are not queued and
|
||||
* will not be processed. A client that connects to continue with a sequence
|
||||
* number will not receive such a message.
|
||||
*
|
||||
* ### Service
|
||||
*
|
||||
* Service messages are like transient messages but are evaluated by the
|
||||
* server. They are mainly used to interact with the server. State-of-health
|
||||
* messages and sync messages are typical service messages.
|
||||
*/
|
||||
class SC_SYSTEM_CLIENT_API Protocol : public Core::InterruptibleObject {
|
||||
// ----------------------------------------------------------------------
|
||||
// Public types
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
struct State {
|
||||
State();
|
||||
uint64_t localSequenceNumber;
|
||||
OPT(uint64_t) sequenceNumber;
|
||||
uint64_t receivedMessages;
|
||||
uint64_t sentMessages;
|
||||
uint64_t bytesSent;
|
||||
uint64_t bytesReceived;
|
||||
uint64_t bytesBuffered;
|
||||
uint64_t maxBufferedBytes;
|
||||
uint64_t maxInboxSize;
|
||||
uint64_t maxOutboxSize;
|
||||
uint64_t systemReadCalls;
|
||||
uint64_t systemWriteCalls;
|
||||
};
|
||||
|
||||
MAKEENUM(
|
||||
ContentEncoding,
|
||||
EVALUES(
|
||||
Identity,
|
||||
Deflate,
|
||||
GZip,
|
||||
LZ4
|
||||
),
|
||||
ENAMES(
|
||||
"identity",
|
||||
"deflate",
|
||||
"gzip",
|
||||
"lz4"
|
||||
)
|
||||
);
|
||||
|
||||
MAKEENUM(
|
||||
ContentType,
|
||||
EVALUES(
|
||||
Binary,
|
||||
JSON,
|
||||
BSON,
|
||||
XML,
|
||||
IMPORTED_XML,
|
||||
Text
|
||||
),
|
||||
ENAMES(
|
||||
"application/x-sc-bin",
|
||||
"text/json",
|
||||
"application/x-sc-bson",
|
||||
"application/x-sc-xml",
|
||||
"text/xml",
|
||||
"text/plain"
|
||||
)
|
||||
);
|
||||
|
||||
MAKEENUM(
|
||||
MessageType,
|
||||
EVALUES(
|
||||
Regular,
|
||||
Transient,
|
||||
Status
|
||||
),
|
||||
ENAMES(
|
||||
"regular",
|
||||
"transient",
|
||||
"status"
|
||||
)
|
||||
);
|
||||
|
||||
static const std::string STATUS_GROUP;
|
||||
static const std::string LISTENER_GROUP;
|
||||
static const std::string IMPORT_GROUP;
|
||||
|
||||
//! A list of group names
|
||||
using Groups = std::set<std::string>;
|
||||
using KeyValueStore = std::map<std::string, std::string>;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// X'truction
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
Protocol();
|
||||
virtual ~Protocol();
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Public interface
|
||||
// ----------------------------------------------------------------------
|
||||
public:
|
||||
/**
|
||||
* @brief Sets whether membership info of clients should be received.
|
||||
* This information informs about when another client enters
|
||||
* one of the groups this connection is subscribed to, when
|
||||
* another clients leaves one of the groups this connection is
|
||||
* subscribed to and when a client disconnects from the
|
||||
* broker.
|
||||
* This method has to be called prior to connect to have an
|
||||
* affect.
|
||||
* @param enable true if membership info should be received, false
|
||||
* otherwise.
|
||||
*/
|
||||
void setMembershipInfo(bool enable);
|
||||
|
||||
/**
|
||||
* @brief connect
|
||||
* @param address The connection address, e.g. host:port/queue
|
||||
* @param timeoutMs The timeout in milliseconds
|
||||
* @param clientName The desired client name. If it is nullptr then the
|
||||
* server will choose a random client name.
|
||||
* @return
|
||||
*/
|
||||
virtual Result connect(const char *address, unsigned int timeoutMs,
|
||||
const char *clientName = nullptr) = 0;
|
||||
|
||||
Result connect(const std::string &address, unsigned int timeoutMs,
|
||||
const std::string &clientName = std::string());
|
||||
|
||||
/**
|
||||
* @brief Returns the schema version supported by the remote end.
|
||||
* This requires a successfull connection to be valid.
|
||||
* @return The version of the remote schema
|
||||
*/
|
||||
Core::Version schemaVersion() const;
|
||||
|
||||
/**
|
||||
* @brief Returns configuration parameters as key-value store
|
||||
* returned by the broker.
|
||||
* Those parameters can be used or not, it is up to the user of
|
||||
* the connection.
|
||||
* @return The key-value store with additional parameters
|
||||
*/
|
||||
const KeyValueStore &extendedParameters() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the client name. Either the one given during connect
|
||||
* or the one assigned by the server.
|
||||
* @return The client name
|
||||
*/
|
||||
const std::string &clientName() const;
|
||||
|
||||
/**
|
||||
* @brief Subscribes to a group which must exist
|
||||
* @param group The group name
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result subscribe(const std::string &group) = 0;
|
||||
|
||||
/**
|
||||
* @brief Unsubscribes from a group where the client was subscribed to.
|
||||
* @param group The group name
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result unsubscribe(const std::string &group) = 0;
|
||||
|
||||
/**
|
||||
* @brief Sends data with a particular content type.
|
||||
* @param targetGroup The group name to send the message to
|
||||
* @param data The data pointer to the octett stream.
|
||||
* @param len Length in bytes of the octett stream.
|
||||
* @param encoding The data content encoding.
|
||||
* @param type The data content type.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result sendData(const std::string &targetGroup,
|
||||
const char *data, size_t len,
|
||||
MessageType type,
|
||||
ContentEncoding contentEncoding,
|
||||
ContentType contentType) = 0;
|
||||
|
||||
/**
|
||||
* @brief Sends a message. A message is actually a binary stream
|
||||
* of certain length. Optionally a content type can be
|
||||
* associated with it.
|
||||
* @param targetGroup The group name to send the message to
|
||||
* @param msg The message pointer.
|
||||
* @param contentType An optional content type which will be or
|
||||
* won't be associated with the packet. This is
|
||||
* implementation specific.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result sendMessage(const std::string &targetGroup,
|
||||
const Core::Message *msg,
|
||||
MessageType type = Regular,
|
||||
OPT(ContentEncoding) contentEncoding = Core::None,
|
||||
OPT(ContentType) contentType = Core::None) = 0;
|
||||
|
||||
/**
|
||||
* @brief Receives a data packet.
|
||||
* The call will block if the local inbox is empty.
|
||||
* @param p The packet instance which will hold the packet
|
||||
* information and the payload.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result recv(Packet &p) = 0;
|
||||
|
||||
/**
|
||||
* @brief Receives a data packet.
|
||||
* The call will block if the local inbox is empty.
|
||||
* @param result An optional storage for the result code
|
||||
* @return A packet pointer which must be handled by the caller.
|
||||
*/
|
||||
virtual Packet *recv(Result *result = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* @brief Waits for a new message to arrive so that a subsequent call
|
||||
* to \ref recv will return immediately.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result fetchInbox() = 0;
|
||||
|
||||
/**
|
||||
* @brief Synchronizes the outbox with the remote server.
|
||||
* @details This means if this method returns successfully then all
|
||||
* sent messages have been acknowledged by the remote end.
|
||||
* This operation blocks until all messages have been
|
||||
* acknowledged.
|
||||
* Writing is not possible while the function is running even
|
||||
* from another thread.
|
||||
* Usually this function does not need to be called from
|
||||
* user code. It is there for completeness to allow clients
|
||||
* to be sure that all messages were handled by the server
|
||||
* at a certain point in time without having to disconnect.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result syncOutbox() = 0;
|
||||
|
||||
/**
|
||||
* @brief Disconnects gracefully from the broker. It sends a disconnect
|
||||
* message and wait for the receipt. In contrast to close, this
|
||||
* is the nice way to say 'good bye'.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result disconnect() = 0;
|
||||
|
||||
/**
|
||||
* @brief Checks for an active connection.
|
||||
* @return True if a connection is established, false otherwise
|
||||
*/
|
||||
virtual bool isConnected() = 0;
|
||||
|
||||
/**
|
||||
* @brief Closes the underlying socket and resources. This is the
|
||||
* hard way to close a connection.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result close() = 0;
|
||||
|
||||
/**
|
||||
* @brief Sets the read timeout for receiving a message. If the
|
||||
* timeout hits then TimeoutError is returned.
|
||||
* @param milliseconds The timeout in milliseconds. Zero or a negative
|
||||
* value disabled the timeout.
|
||||
* @return Result code
|
||||
*/
|
||||
virtual Result setTimeout(int milliseconds) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the names of the available message groups.
|
||||
* @details This call only returns valid content after a connection
|
||||
* was established. If a reconnect occurred during the
|
||||
* lifetime of the connection and the groups of the queue
|
||||
* have changed then this will be reflected in the returned
|
||||
* vector.
|
||||
* @return The available groups
|
||||
*/
|
||||
const Groups &groups() const;
|
||||
|
||||
bool erroneous() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the error message corresponding to the last
|
||||
* erroneous call.
|
||||
* @return The message or empty.
|
||||
*/
|
||||
const std::string &lastErrorMessage() const;
|
||||
|
||||
const State &state() const;
|
||||
|
||||
/**
|
||||
* @brief Queries the local message inbox size. It is safe to call this
|
||||
* method from separate threads.
|
||||
* @return The number of messages queued in the local inbox.
|
||||
*/
|
||||
size_t inboxSize() const;
|
||||
|
||||
/**
|
||||
* @brief Queries the local message outbox size. If a message is still
|
||||
* in the outbox does not mean that is hasn't been sent over the
|
||||
* wire. It just means that the server hasn't acknowledged the
|
||||
* message yet and that in case of a reconnect the outbox will
|
||||
* be sent again.
|
||||
* @return The number of unacknowledged messages.
|
||||
*/
|
||||
virtual size_t outboxSize() const = 0;
|
||||
|
||||
void setCertificate(const std::string &cert);
|
||||
|
||||
static Core::Message *decode(const std::string &blob,
|
||||
ContentEncoding encoding,
|
||||
ContentType type);
|
||||
|
||||
static Core::Message *decode(const char *blob, size_t blob_length,
|
||||
ContentEncoding encoding,
|
||||
ContentType type);
|
||||
|
||||
static bool encode(std::string &blob, const Core::Message *msg,
|
||||
ContentEncoding encoding, ContentType type,
|
||||
int schemaVersion);
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Interruptible interface
|
||||
// ----------------------------------------------------------------------
|
||||
protected:
|
||||
virtual void handleInterrupt(int) override;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Protected methods
|
||||
// ----------------------------------------------------------------------
|
||||
protected:
|
||||
void queuePacket(Packet *p);
|
||||
|
||||
/**
|
||||
* Clears all messages in the inbox. This method is not intended for
|
||||
* public use. Note that it does not lock the read mutex.
|
||||
*/
|
||||
void clearInbox();
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Private types and members
|
||||
// ----------------------------------------------------------------------
|
||||
protected:
|
||||
using PacketQueue = std::deque<Packet*>;
|
||||
|
||||
bool _wantMembershipInfo;
|
||||
Groups _groups;
|
||||
PacketQueue _inbox;
|
||||
std::string _errorMessage;
|
||||
State _state;
|
||||
std::string _registeredClientName;
|
||||
Core::Version _schemaVersion; //!< The schema version the
|
||||
//!< server supports
|
||||
KeyValueStore _extendedParameters;
|
||||
std::string _certificate; //!< Optional client certificate
|
||||
|
||||
// Mutexes to synchronize read access from separate threads.
|
||||
mutable std::mutex _readMutex;
|
||||
};
|
||||
|
||||
|
||||
DEFINE_INTERFACE_FACTORY(Protocol);
|
||||
|
||||
#define REGISTER_CONNECTION_PROTOCOL(Class, Service) \
|
||||
Seiscomp::Core::Generic::InterfaceFactory<Seiscomp::Client::Protocol, Class> __##Class##InterfaceFactory__(Service)
|
||||
|
||||
|
||||
inline Core::Version Protocol::schemaVersion() const {
|
||||
return _schemaVersion;
|
||||
}
|
||||
|
||||
inline const Protocol::KeyValueStore &Protocol::extendedParameters() const {
|
||||
return _extendedParameters;
|
||||
}
|
||||
|
||||
inline const std::string &Protocol::clientName() const {
|
||||
return _registeredClientName;
|
||||
}
|
||||
|
||||
inline bool Protocol::erroneous() const {
|
||||
return !_errorMessage.empty();
|
||||
}
|
||||
|
||||
inline const std::string &Protocol::lastErrorMessage() const {
|
||||
return _errorMessage;
|
||||
}
|
||||
|
||||
inline const Protocol::State &Protocol::state() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
119
include/seiscomp/messaging/status.h
Normal file
119
include/seiscomp/messaging/status.h
Normal file
@ -0,0 +1,119 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_CLIENT_STATUS_H
|
||||
#define SEISCOMP_CLIENT_STATUS_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <seiscomp/core/enumeration.h>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
namespace Client {
|
||||
|
||||
|
||||
struct Status {
|
||||
MAKEENUM(
|
||||
Tag,
|
||||
EVALUES(
|
||||
Time,
|
||||
Hostname,
|
||||
Clientname,
|
||||
Programname,
|
||||
PID,
|
||||
CPUUsage,
|
||||
TotalMemory,
|
||||
ClientMemoryUsage,
|
||||
SentMessages,
|
||||
SentBytes,
|
||||
ReceivedMessages,
|
||||
ReceivedBytes,
|
||||
MessageQueueSize,
|
||||
ObjectCount,
|
||||
Address,
|
||||
Uptime,
|
||||
ResponseTime
|
||||
),
|
||||
ENAMES(
|
||||
"time",
|
||||
"hostname",
|
||||
"clientname",
|
||||
"programname",
|
||||
"pid",
|
||||
"cpuusage",
|
||||
"totalmemory",
|
||||
"clientmemoryusage",
|
||||
"sentmessages",
|
||||
"sentbytes",
|
||||
"receivedmessages",
|
||||
"receivedbytes",
|
||||
"messagequeuesize",
|
||||
"objectcount",
|
||||
"address",
|
||||
"uptime",
|
||||
"responsetime"
|
||||
)
|
||||
);
|
||||
|
||||
void clear();
|
||||
bool parse(const std::string &data);
|
||||
|
||||
std::string values[ETagQuantity];
|
||||
};
|
||||
|
||||
|
||||
// Primary Template
|
||||
template <Status::ETag T>
|
||||
struct StatusT;
|
||||
|
||||
|
||||
// Specializations
|
||||
#define SPECIALIZE_CONNECTIONINFOT(TAG, TYPE) \
|
||||
template <> struct StatusT<TAG> { \
|
||||
typedef TYPE Type; \
|
||||
};
|
||||
|
||||
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::Time, std::string)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::Hostname, std::string)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::Clientname, std::string)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::Programname, std::string)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::PID, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::CPUUsage, double)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::TotalMemory, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::ClientMemoryUsage, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::SentMessages, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::SentBytes, uint64_t)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::ReceivedMessages, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::ReceivedBytes, uint64_t)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::MessageQueueSize, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::ObjectCount, int)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::Address, std::string)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::Uptime, std::string)
|
||||
SPECIALIZE_CONNECTIONINFOT(Status::ResponseTime, int)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user