]> granicus.if.org Git - icinga2/commitdiff
De-coupled JSON parsing from the Netstring class.
authorGunnar Beutner <gunnar.beutner@netways.de>
Sun, 13 May 2012 08:44:03 +0000 (10:44 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Sun, 13 May 2012 08:44:03 +0000 (10:44 +0200)
base/i2-base.h
base/timer.cpp
icinga/endpointmanager.cpp
icinga/endpointmanager.h
jsonrpc/jsonrpcclient.cpp
jsonrpc/message.cpp
jsonrpc/message.h
jsonrpc/netstring.cpp
jsonrpc/netstring.h

index 1d58c50831f2d7429668ca4720d12456c88409fc..771708887ba9f487885cac47865d05b568d52df2 100644 (file)
@@ -57,6 +57,8 @@
 #include <typeinfo>
 #include <map>
 #include <list>
+#include <algorithm>
+#include <functional>
 
 #if defined(__APPLE__) && defined(__MACH__)
 #      pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
index 5efae498379541432e2285672dad73d242ae1166..2cda9debb37dedcc4fd0a6b8a16226b497a7a510 100644 (file)
@@ -17,8 +17,6 @@
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
  ******************************************************************************/
 
-#include <functional>
-#include <algorithm>
 #include "i2-base.h"
 
 using namespace icinga;
index f49a81e8a0918fa3472bf54a779604ccaf74d315..83e2f7b88a1deb5f25be9c49a4ba14772cd4c542 100644 (file)
@@ -68,7 +68,7 @@ void EndpointManager::AddConnection(string node, string service)
 
 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());
 }
 
@@ -86,7 +86,9 @@ int EndpointManager::NewClientHandler(const NewClientEventArgs& ncea)
 
 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
 }
 
@@ -96,7 +98,7 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint)
                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();
@@ -106,7 +108,9 @@ void EndpointManager::RegisterEndpoint(Endpoint::Ptr endpoint)
 
 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)
@@ -123,7 +127,7 @@ void EndpointManager::SendUnicastRequest(Endpoint::Ptr sender, Endpoint::Ptr rec
                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);
        }
 }
@@ -145,7 +149,7 @@ void EndpointManager::SendMulticastRequest(Endpoint::Ptr sender, const JsonRpcRe
        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);
        }
@@ -156,7 +160,7 @@ void EndpointManager::ForEachEndpoint(function<int (const NewEndpointEventArgs&)
        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++;
@@ -168,7 +172,7 @@ void EndpointManager::ForEachEndpoint(function<int (const NewEndpointEventArgs&)
 
 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;
index 96ececa797bd0ecb9c4cb3eb7184763de1bc179f..b866a83f8f13d0b7c36960df93055154c7cf5433 100644 (file)
@@ -33,8 +33,8 @@ class I2_ICINGA_API EndpointManager : public Object
        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);
index 46391948edda637ebc651443aac8925aa88df7d8..0f12adf6e93b4a3e37876af2aa7dcb4377db01b2 100644 (file)
@@ -33,18 +33,21 @@ void JsonRpcClient::Start(void)
 
 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;
index b6dc68c0aaa213cc1a03ebb32febd514408508ec..f25ff7ec7c616428859b4e16512381b8e5f6885b 100644 (file)
@@ -18,6 +18,7 @@
  ******************************************************************************/
 
 #include "i2-jsonrpc.h"
+#include <cJSON.h>
 
 using namespace icinga;
 
@@ -26,6 +27,18 @@ Message::Message(void)
        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;
@@ -36,6 +49,80 @@ Message::Message(const Message& message)
        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;
index d77b0f12ce9f34357c5db7f76f78ed330fa7f143..ddca1dcf8a780c0cc7739356e7287f5060922f85 100644 (file)
 #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;
index c05ba7925fcab5176506819ba70887986eb0a0d3..307f16b5d407dbc8a27e73e44563bce3b2cec957 100644 (file)
  * 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();
@@ -113,45 +58,22 @@ bool Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo, Message *message)
        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);
 }
index 732fcad874348858e7bad63a0ffd9c50b080abc3..4f264ccd1340af9955f69cd836d962cef7219b8d 100644 (file)
 #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);
 };
 
 }