#include <typeinfo>
#include <map>
#include <list>
+#include <algorithm>
+#include <functional>
#if defined(__APPLE__) && defined(__MACH__)
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
-#include <functional>
-#include <algorithm>
#include "i2-base.h"
using namespace icinga;
void EndpointManager::RegisterServer(JsonRpcServer::Ptr server)
{
- m_Servers.push_front(server);
+ m_Servers.push_back(server);
server->OnNewClient += bind_weak(&EndpointManager::NewClientHandler, shared_from_this());
}
void EndpointManager::UnregisterServer(JsonRpcServer::Ptr server)
{
- m_Servers.remove(server);
+ m_Servers.erase(
+ remove(m_Servers.begin(), m_Servers.end(), server),
+ m_Servers.end());
// TODO: unbind event
}
throw InvalidArgumentException("Identity must be empty.");
endpoint->SetEndpointManager(static_pointer_cast<EndpointManager>(shared_from_this()));
- m_Endpoints.push_front(endpoint);
+ m_Endpoints.push_back(endpoint);
NewEndpointEventArgs neea;
neea.Source = shared_from_this();
void EndpointManager::UnregisterEndpoint(Endpoint::Ptr endpoint)
{
- m_Endpoints.remove(endpoint);
+ m_Endpoints.erase(
+ remove(m_Endpoints.begin(), m_Endpoints.end(), endpoint),
+ m_Endpoints.end());
}
void EndpointManager::SendUnicastRequest(Endpoint::Ptr sender, Endpoint::Ptr recipient, const JsonRpcRequest& request, bool fromLocal)
throw InvalidArgumentException("Missing 'method' parameter.");
if (recipient->IsMethodSink(method)) {
- Application::Log(sender->GetAddress() + " -> " + recipient->GetAddress() + ": " + method);
+ //Application::Log(sender->GetAddress() + " -> " + recipient->GetAddress() + ": " + method);
recipient->ProcessRequest(sender, request);
}
}
if (!request.GetMethod(&method))
throw InvalidArgumentException("Message is missing the 'method' property.");
- for (list<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
+ for (vector<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
{
SendUnicastRequest(sender, *i, request, fromLocal);
}
NewEndpointEventArgs neea;
neea.Source = shared_from_this();
- list<Endpoint::Ptr>::iterator prev, i;
+ vector<Endpoint::Ptr>::iterator prev, i;
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); ) {
prev = i;
i++;
Endpoint::Ptr EndpointManager::GetEndpointByIdentity(string identity) const
{
- list<Endpoint::Ptr>::const_iterator i;
+ vector<Endpoint::Ptr>::const_iterator i;
for (i = m_Endpoints.begin(); i != m_Endpoints.end(); i++) {
if ((*i)->GetIdentity() == identity)
return *i;
string m_Identity;
shared_ptr<SSL_CTX> m_SSLContext;
- list<JsonRpcServer::Ptr> m_Servers;
- list<Endpoint::Ptr> m_Endpoints;
+ vector<JsonRpcServer::Ptr> m_Servers;
+ vector<Endpoint::Ptr> m_Endpoints;
void RegisterServer(JsonRpcServer::Ptr server);
void UnregisterServer(JsonRpcServer::Ptr server);
void JsonRpcClient::SendMessage(const Message& message)
{
- Netstring::WriteMessageToFIFO(GetSendQueue(), message);
+ Netstring::WriteStringToFIFO(GetSendQueue(), message.ToJsonString());
}
int JsonRpcClient::DataAvailableHandler(const EventArgs&)
{
for (;;) {
try {
+ string jsonString;
Message message;
- if (!Netstring::ReadMessageFromFIFO(GetRecvQueue(), &message))
+ if (!Netstring::ReadStringFromFIFO(GetRecvQueue(), &jsonString))
break;
+ message = Message(jsonString);
+
NewMessageEventArgs nea;
nea.Source = shared_from_this();
nea.Message = message;
******************************************************************************/
#include "i2-jsonrpc.h"
+#include <cJSON.h>
using namespace icinga;
m_Dictionary = make_shared<Dictionary>();
}
+Message::Message(string jsonString)
+{
+ json_t *json = cJSON_Parse(jsonString.c_str());
+
+ if (!json)
+ throw InvalidArgumentException("Invalid JSON string");
+
+ m_Dictionary = GetDictionaryFromJson(json);
+
+ cJSON_Delete(json);
+}
+
Message::Message(const Dictionary::Ptr& dictionary)
{
m_Dictionary = dictionary;
m_Dictionary = message.GetDictionary();
}
+Dictionary::Ptr Message::GetDictionaryFromJson(json_t *json)
+{
+ Dictionary::Ptr dictionary = make_shared<Dictionary>();
+
+ for (cJSON *i = json->child; i != NULL; i = i->next) {
+ switch (i->type) {
+ case cJSON_Number:
+ dictionary->SetProperty(i->string, i->valueint);
+ break;
+ case cJSON_String:
+ dictionary->SetProperty(i->string, i->valuestring);
+ break;
+ case cJSON_Object:
+ dictionary->SetProperty(i->string, GetDictionaryFromJson(i));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return dictionary;
+}
+
+json_t *Message::GetJsonFromDictionary(const Dictionary::Ptr& dictionary)
+{
+ cJSON *json;
+ string valueString;
+ Dictionary::Ptr valueDictionary;
+
+ json = cJSON_CreateObject();
+
+ for (DictionaryIterator i = dictionary->Begin(); i != dictionary->End(); i++) {
+ switch (i->second.GetType()) {
+ case VariantInteger:
+ cJSON_AddNumberToObject(json, i->first.c_str(), i->second.GetInteger());
+ break;
+ case VariantString:
+ valueString = i->second.GetString();
+ cJSON_AddStringToObject(json, i->first.c_str(), valueString.c_str());
+ break;
+ case VariantObject:
+ valueDictionary = dynamic_pointer_cast<Dictionary>(i->second.GetObject());
+
+ if (valueDictionary)
+ cJSON_AddItemToObject(json, i->first.c_str(), GetJsonFromDictionary(valueDictionary));
+ default:
+ break;
+ }
+ }
+
+ return json;
+}
+
+string Message::ToJsonString(void) const
+{
+ json_t *json = GetJsonFromDictionary(m_Dictionary);
+ char *jsonString;
+ string result;
+
+#ifdef _DEBUG
+ jsonString = cJSON_Print(json);
+#else /* _DEBUG */
+ jsonString = cJSON_PrintUnformatted(json);
+#endif /* _DEBUG */
+
+ cJSON_Delete(json);
+
+ result = jsonString;
+
+ free(jsonString);
+
+ return result;
+}
+
Dictionary::Ptr Message::GetDictionary(void) const
{
return m_Dictionary;
#ifndef MESSAGE_H
#define MESSAGE_H
+struct cJSON;
+
namespace icinga
{
+typedef ::cJSON json_t;
+
class I2_JSONRPC_API Message
{
private:
Dictionary::Ptr m_Dictionary;
+ static Dictionary::Ptr GetDictionaryFromJson(json_t *json);
+ static json_t *GetJsonFromDictionary(const Dictionary::Ptr& dictionary);
+
public:
Message(void);
+ Message(string json);
Message(const Dictionary::Ptr& dictionary);
Message(const Message& message);
+ string ToJsonString(void) const;
+
Dictionary::Ptr GetDictionary(void) const;
bool GetPropertyString(string key, string *value) const;
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
-#include <cstdio>
#include "i2-jsonrpc.h"
-#include <cJSON.h>
using namespace icinga;
-Dictionary::Ptr Netstring::GetDictionaryFromJson(json_t *json)
-{
- Dictionary::Ptr dictionary = make_shared<Dictionary>();
-
- for (cJSON *i = json->child; i != NULL; i = i->next) {
- switch (i->type) {
- case cJSON_Number:
- dictionary->SetProperty(i->string, i->valueint);
- break;
- case cJSON_String:
- dictionary->SetProperty(i->string, i->valuestring);
- break;
- case cJSON_Object:
- dictionary->SetProperty(i->string, GetDictionaryFromJson(i));
- break;
- default:
- break;
- }
- }
-
- return dictionary;
-}
-
-json_t *Netstring::GetJsonFromDictionary(const Dictionary::Ptr& dictionary)
-{
- cJSON *json;
- string valueString;
- Dictionary::Ptr valueDictionary;
-
- json = cJSON_CreateObject();
-
- for (DictionaryIterator i = dictionary->Begin(); i != dictionary->End(); i++) {
- switch (i->second.GetType()) {
- case VariantInteger:
- cJSON_AddNumberToObject(json, i->first.c_str(), i->second.GetInteger());
- break;
- case VariantString:
- valueString = i->second.GetString();
- cJSON_AddStringToObject(json, i->first.c_str(), valueString.c_str());
- break;
- case VariantObject:
- valueDictionary = dynamic_pointer_cast<Dictionary>(i->second.GetObject());
-
- if (valueDictionary)
- cJSON_AddItemToObject(json, i->first.c_str(), GetJsonFromDictionary(valueDictionary));
- default:
- break;
- }
- }
-
- return json;
-}
-
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
-bool Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo, Message *message)
+bool Netstring::ReadStringFromFIFO(FIFO::Ptr fifo, string *str)
{
size_t buffer_length = fifo->GetSize();
char *buffer = (char *)fifo->GetReadBuffer();
if (buffer[i + len] != ',')
throw InvalidArgumentException("Invalid Netstring (missing ,)");
- /* nuke the comma delimiter */
- buffer[i + len] = '\0';
- cJSON *object = cJSON_Parse(&buffer[i]);
-
- if (object == NULL) {
- /* restore the comma */
- buffer[i + len] = ',';
- throw InvalidArgumentException("Invalid JSON string");
- }
+ *str = string(&buffer[i], &buffer[i + len]);
/* remove the data from the fifo */
fifo->Read(NULL, i + len + 1);
- *message = Message(GetDictionaryFromJson(object));
- cJSON_Delete(object);
return true;
}
-void Netstring::WriteMessageToFIFO(FIFO::Ptr fifo, const Message& message)
+void Netstring::WriteStringToFIFO(FIFO::Ptr fifo, const string& str)
{
- char *json;
- cJSON *object = GetJsonFromDictionary(message.GetDictionary());
- size_t len;
-
-#ifdef _DEBUG
- json = cJSON_Print(object);
-#else /* _DEBUG */
- json = cJSON_PrintUnformatted(object);
-#endif /* _DEBUG */
-
- cJSON_Delete(object);
-
- len = strlen(json);
+ unsigned long len = str.size();
char strLength[50];
sprintf(strLength, "%lu:", (unsigned long)len);
fifo->Write(strLength, strlen(strLength));
- fifo->Write(json, len);
- free(json);
+ fifo->Write(str.c_str(), len);
fifo->Write(",", 1);
}
#ifndef NETSTRING_H
#define NETSTRING_H
-struct cJSON;
-
namespace icinga
{
-typedef ::cJSON json_t;
-
class I2_JSONRPC_API Netstring : public Object
{
-private:
- size_t m_Length;
- void *m_Data;
-
- static Dictionary::Ptr GetDictionaryFromJson(json_t *json);
- static json_t *GetJsonFromDictionary(const Dictionary::Ptr& dictionary);
-
public:
typedef shared_ptr<Netstring> Ptr;
typedef weak_ptr<Netstring> WeakPtr;
- static bool ReadMessageFromFIFO(FIFO::Ptr fifo, Message *message);
- static void WriteMessageToFIFO(FIFO::Ptr fifo, const Message& message);
+ static bool ReadStringFromFIFO(FIFO::Ptr fifo, string *message);
+ static void WriteStringToFIFO(FIFO::Ptr fifo, const string& message);
};
}