mirror of https://github.com/Icinga/icinga2.git
Refactored JSON/message code.
This commit is contained in:
parent
40b45c3d91
commit
ab32aa4f71
|
@ -21,8 +21,6 @@ public:
|
|||
string GetMessage(void) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define DEFINE_EXCEPTION_CLASS(klass) \
|
||||
class klass : public Exception \
|
||||
{ \
|
||||
|
@ -39,4 +37,9 @@ public:
|
|||
} \
|
||||
};
|
||||
|
||||
DEFINE_EXCEPTION_CLASS(NotImplementedException);
|
||||
DEFINE_EXCEPTION_CLASS(InvalidArgumentException);
|
||||
|
||||
}
|
||||
|
||||
#endif /* EXCEPTION_H */
|
||||
|
|
|
@ -183,7 +183,8 @@ int ConfigRpcComponent::RemoteObjectUpdatedHandler(NewMessageEventArgs::Ptr ea)
|
|||
|
||||
int ConfigRpcComponent::RemoteObjectRemovedHandler(NewMessageEventArgs::Ptr ea)
|
||||
{
|
||||
JsonRpcMessage::Ptr message = ea->Message;
|
||||
JsonRpcRequest::Ptr message = ea->Message->Cast<JsonRpcRequest>();
|
||||
Message::Ptr params = message->GetParams();
|
||||
string name, type;
|
||||
|
||||
if (!message->GetParamString("name", &name))
|
||||
|
|
|
@ -6,6 +6,7 @@ EndProject
|
|||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsonrpc", "jsonrpc\jsonrpc.vcxproj", "{8DD52FAC-ECEE-48C2-B266-E7C47ED485F8}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{66BED474-C33F-48F9-90BA-BBCFEDC006B8} = {66BED474-C33F-48F9-90BA-BBCFEDC006B8}
|
||||
{4F00EE82-B829-4872-B8F0-C1A8D86C94B4} = {4F00EE82-B829-4872-B8F0-C1A8D86C94B4}
|
||||
{9C92DA90-FD53-43A9-A244-90F2E8AF9677} = {9C92DA90-FD53-43A9-A244-90F2E8AF9677}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
@ -32,6 +33,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "configrpc", "components\con
|
|||
{C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} = {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msgc", "msgc\msgc.vcxproj", "{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -66,6 +69,10 @@ Global
|
|||
{697C6D7E-3109-484C-A7AF-384D28711610}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{697C6D7E-3109-484C-A7AF-384D28711610}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{697C6D7E-3109-484C-A7AF-384D28711610}.Release|Win32.Build.0 = Release|Win32
|
||||
{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -2,17 +2,32 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
Endpoint::Endpoint(void)
|
||||
void Endpoint::RegisterMethodSink(string method)
|
||||
{
|
||||
m_Connected = false;
|
||||
m_MethodSinks.insert(method);
|
||||
}
|
||||
|
||||
void Endpoint::SetConnected(bool connected)
|
||||
void Endpoint::UnregisterMethodSink(string method)
|
||||
{
|
||||
m_Connected = connected;
|
||||
m_MethodSinks.erase(method);
|
||||
}
|
||||
|
||||
bool Endpoint::GetConnected(void)
|
||||
bool Endpoint::IsMethodSink(string method)
|
||||
{
|
||||
return m_Connected;
|
||||
return (m_MethodSinks.find(method) != m_MethodSinks.end());
|
||||
}
|
||||
|
||||
void Endpoint::RegisterMethodSource(string method)
|
||||
{
|
||||
m_MethodSources.insert(method);
|
||||
}
|
||||
|
||||
void Endpoint::UnregisterMethodSource(string method)
|
||||
{
|
||||
m_MethodSources.erase(method);
|
||||
}
|
||||
|
||||
bool Endpoint::IsMethodSource(string method)
|
||||
{
|
||||
return (m_MethodSources.find(method) != m_MethodSinks.end());
|
||||
}
|
||||
|
|
|
@ -9,18 +9,23 @@ class EndpointManager;
|
|||
class I2_ICINGA_API Endpoint : public Object
|
||||
{
|
||||
private:
|
||||
bool m_Connected;
|
||||
set<string> m_MethodSinks;
|
||||
set<string> m_MethodSources;
|
||||
|
||||
public:
|
||||
typedef shared_ptr<Endpoint> Ptr;
|
||||
typedef weak_ptr<Endpoint> WeakPtr;
|
||||
|
||||
Endpoint(void);
|
||||
void RegisterMethodSink(string method);
|
||||
void UnregisterMethodSink(string method);
|
||||
bool IsMethodSink(string method);
|
||||
|
||||
virtual void SetConnected(bool connected);
|
||||
virtual bool GetConnected(void);
|
||||
void RegisterMethodSource(string method);
|
||||
void UnregisterMethodSource(string method);
|
||||
bool IsMethodSource(string method);
|
||||
|
||||
virtual void SendMessage(Endpoint::Ptr source, JsonRpcMessage::Ptr message) = 0;
|
||||
virtual void SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message) = 0;
|
||||
virtual void SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -121,19 +121,31 @@ void EndpointManager::UnregisterEndpoint(Endpoint::Ptr endpoint)
|
|||
m_Endpoints.remove(endpoint);
|
||||
}
|
||||
|
||||
void EndpointManager::SendMessage(Endpoint::Ptr source, Endpoint::Ptr destination, JsonRpcMessage::Ptr message)
|
||||
void EndpointManager::SendAnycastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request)
|
||||
{
|
||||
if (destination) {
|
||||
destination->SendMessage(source, message);
|
||||
} else {
|
||||
for (list<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
|
||||
{
|
||||
Endpoint::Ptr endpoint = *i;
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
if (endpoint == source)
|
||||
continue;
|
||||
void EndpointManager::SendMulticastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
string id;
|
||||
if (request->GetID(&id))
|
||||
throw InvalidArgumentException("Multicast requests must not have an ID.");
|
||||
#endif /* _DEBUG */
|
||||
|
||||
endpoint->SendMessage(source, message);
|
||||
}
|
||||
string method;
|
||||
if (!request->GetMethod(&method))
|
||||
throw InvalidArgumentException();
|
||||
|
||||
for (list<Endpoint::Ptr>::iterator i = m_Endpoints.begin(); i != m_Endpoints.end(); i++)
|
||||
{
|
||||
Endpoint::Ptr endpoint = *i;
|
||||
|
||||
if (endpoint == sender)
|
||||
continue;
|
||||
|
||||
if (endpoint->IsMethodSink(method))
|
||||
endpoint->SendRequest(sender, request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ public:
|
|||
void RegisterEndpoint(Endpoint::Ptr endpoint);
|
||||
void UnregisterEndpoint(Endpoint::Ptr endpoint);
|
||||
|
||||
void SendMessage(Endpoint::Ptr source, Endpoint::Ptr destination, JsonRpcMessage::Ptr message);
|
||||
void SendAnycastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request);
|
||||
void SendMulticastRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <i2-base.h>
|
||||
#include <i2-jsonrpc.h>
|
||||
#include <set>
|
||||
|
||||
#ifdef I2_ICINGA_BUILD
|
||||
# define I2_ICINGA_API I2_EXPORT
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
#include "i2-icinga.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
JsonRpcClient::Ptr JsonRpcEndpoint::GetClient(void)
|
||||
{
|
||||
return m_Client;
|
||||
}
|
||||
|
||||
void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client)
|
||||
{
|
||||
m_Client = client;
|
||||
}
|
||||
|
||||
bool JsonRpcEndpoint::IsConnected(void) const
|
||||
{
|
||||
return (m_Client.get() != NULL);
|
||||
}
|
||||
|
||||
void JsonRpcEndpoint::SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message)
|
||||
{
|
||||
if (IsConnected())
|
||||
m_Client->SendMessage(message);
|
||||
}
|
||||
|
||||
void JsonRpcEndpoint::SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message)
|
||||
{
|
||||
if (IsConnected())
|
||||
m_Client->SendMessage(message);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,19 @@ namespace icinga
|
|||
|
||||
class I2_ICINGA_API JsonRpcEndpoint : public Endpoint
|
||||
{
|
||||
private:
|
||||
JsonRpcClient::Ptr m_Client;
|
||||
|
||||
bool IsConnected(void) const;
|
||||
|
||||
public:
|
||||
JsonRpcEndpoint(void);
|
||||
|
||||
JsonRpcClient::Ptr GetClient(void);
|
||||
void SetClient(JsonRpcClient::Ptr client);
|
||||
|
||||
virtual void SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message);
|
||||
virtual void SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -2,47 +2,42 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
VirtualEndpoint::VirtualEndpoint()
|
||||
{
|
||||
SetConnected(true);
|
||||
}
|
||||
|
||||
void VirtualEndpoint::RegisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback)
|
||||
void VirtualEndpoint::RegisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback)
|
||||
{
|
||||
m_MethodHandlers[method] += callback;
|
||||
|
||||
RegisterMethodSink(method);
|
||||
}
|
||||
|
||||
void VirtualEndpoint::UnregisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback)
|
||||
void VirtualEndpoint::UnregisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback)
|
||||
{
|
||||
// TODO: implement
|
||||
//m_Methods[method] -= callback;
|
||||
//m_MethodHandlers[method] -= callback;
|
||||
//UnregisterMethodSink(method);
|
||||
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
||||
void VirtualEndpoint::RegisterMethodSource(string method)
|
||||
void VirtualEndpoint::SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr request)
|
||||
{
|
||||
m_MethodSources.push_front(method);
|
||||
string method;
|
||||
if (!request->GetMethod(&method))
|
||||
return;
|
||||
|
||||
map<string, Event<NewRequestEventArgs::Ptr> >::iterator i = m_MethodHandlers.find(method);
|
||||
|
||||
if (i == m_MethodHandlers.end())
|
||||
throw InvalidArgumentException();
|
||||
|
||||
NewRequestEventArgs::Ptr nrea = make_shared<NewRequestEventArgs>();
|
||||
nrea->Source = shared_from_this();
|
||||
nrea->Sender = sender;
|
||||
nrea->Request = request;
|
||||
i->second(nrea);
|
||||
}
|
||||
|
||||
void VirtualEndpoint::UnregisterMethodSource(string method)
|
||||
void VirtualEndpoint::SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr response)
|
||||
{
|
||||
m_MethodSources.remove(method);
|
||||
}
|
||||
|
||||
void VirtualEndpoint::SendMessage(Endpoint::Ptr source, JsonRpcMessage::Ptr message)
|
||||
{
|
||||
map<string, Event<NewMessageEventArgs::Ptr> >::iterator i;
|
||||
i = m_MethodHandlers.find(message->GetMethod());
|
||||
|
||||
if (i == m_MethodHandlers.end()) {
|
||||
JsonRpcMessage::Ptr response = make_shared<JsonRpcMessage>();
|
||||
response->SetVersion("2.0");
|
||||
response->SetError("Unknown method.");
|
||||
response->SetID(message->GetID());
|
||||
source->SendMessage(static_pointer_cast<Endpoint>(shared_from_this()), response);
|
||||
}
|
||||
|
||||
NewMessageEventArgs::Ptr nmea = make_shared<NewMessageEventArgs>();
|
||||
nmea->Source = shared_from_this();
|
||||
nmea->Message = message;
|
||||
i->second(nmea);
|
||||
// TODO: figure out which request this response belongs to and notify the caller
|
||||
throw NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -4,25 +4,32 @@
|
|||
namespace icinga
|
||||
{
|
||||
|
||||
struct I2_JSONRPC_API NewRequestEventArgs : public EventArgs
|
||||
{
|
||||
typedef shared_ptr<NewRequestEventArgs> Ptr;
|
||||
typedef weak_ptr<NewRequestEventArgs> WeakPtr;
|
||||
|
||||
Endpoint::Ptr Sender;
|
||||
JsonRpcRequest::Ptr Request;
|
||||
};
|
||||
|
||||
class I2_ICINGA_API VirtualEndpoint : public Endpoint
|
||||
{
|
||||
private:
|
||||
map< string, Event<NewMessageEventArgs::Ptr> > m_MethodHandlers;
|
||||
list<string> m_MethodSources;
|
||||
map< string, Event<NewRequestEventArgs::Ptr> > m_MethodHandlers;
|
||||
|
||||
public:
|
||||
typedef shared_ptr<VirtualEndpoint> Ptr;
|
||||
typedef weak_ptr<VirtualEndpoint> WeakPtr;
|
||||
|
||||
VirtualEndpoint();
|
||||
|
||||
virtual void RegisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback);
|
||||
virtual void UnregisterMethodHandler(string method, function<int (NewMessageEventArgs::Ptr)> callback);
|
||||
void RegisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback);
|
||||
void UnregisterMethodHandler(string method, function<int (NewRequestEventArgs::Ptr)> callback);
|
||||
|
||||
virtual void RegisterMethodSource(string method);
|
||||
virtual void UnregisterMethodSource(string method);
|
||||
|
||||
virtual void SendMessage(Endpoint::Ptr source, JsonRpcMessage::Ptr message);
|
||||
virtual void SendRequest(Endpoint::Ptr sender, JsonRpcRequest::Ptr message);
|
||||
virtual void SendResponse(Endpoint::Ptr sender, JsonRpcResponse::Ptr message);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
# define I2_JSONRPC_API I2_IMPORT
|
||||
#endif /* I2_JSONRPC_BUILD */
|
||||
|
||||
#include "message.h"
|
||||
#include "netstring.h"
|
||||
#include "jsonrpcmessage.h"
|
||||
#include "jsonrpcrequest.h"
|
||||
#include "jsonrpcresponse.h"
|
||||
#include "jsonrpcclient.h"
|
||||
#include "jsonrpcserver.h"
|
||||
|
||||
|
|
|
@ -13,16 +13,48 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="i2-jsonrpc.h" />
|
||||
<ClInclude Include="jsonrpcclient.h" />
|
||||
<ClInclude Include="jsonrpcmessage.h" />
|
||||
<ClInclude Include="jsonrpcrequest.h" />
|
||||
<ClInclude Include="jsonrpcresponse.h" />
|
||||
<ClInclude Include="jsonrpcserver.h" />
|
||||
<ClInclude Include="message.h" />
|
||||
<ClInclude Include="netstring.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jsonrpcclient.cpp" />
|
||||
<ClCompile Include="jsonrpcmessage.cpp" />
|
||||
<ClCompile Include="jsonrpcrequest.cpp" />
|
||||
<ClCompile Include="jsonrpcresponse.cpp" />
|
||||
<ClCompile Include="jsonrpcserver.cpp" />
|
||||
<ClCompile Include="message.cpp" />
|
||||
<ClCompile Include="netstring.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="jsonrpcrequest.message">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Identity)</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Identity)</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).cpp %(Filename).h</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).cpp %(Filename).h</Outputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="jsonrpcresponse.message">
|
||||
<FileType>Document</FileType>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).cpp %(Filename).h</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(Filename).cpp %(Filename).h</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling %(Identity)</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling %(Identity)</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(OutputPath)\msgc" %(Identity)</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{8DD52FAC-ECEE-48C2-B266-E7C47ED485F8}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
|
|
|
@ -9,32 +9,30 @@ void JsonRpcClient::Start(void)
|
|||
OnDataAvailable += bind_weak(&JsonRpcClient::DataAvailableHandler, shared_from_this());
|
||||
}
|
||||
|
||||
void JsonRpcClient::SendMessage(JsonRpcMessage::Ptr message)
|
||||
void JsonRpcClient::SendMessage(Message::Ptr message)
|
||||
{
|
||||
Netstring::WriteJSONToFIFO(GetSendQueue(), message->GetJSON());
|
||||
Netstring::WriteMessageToFIFO(GetSendQueue(), message);
|
||||
}
|
||||
|
||||
int JsonRpcClient::DataAvailableHandler(EventArgs::Ptr ea)
|
||||
{
|
||||
cJSON *json;
|
||||
Message::Ptr message;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
json = Netstring::ReadJSONFromFIFO(GetRecvQueue());
|
||||
message = Netstring::ReadMessageFromFIFO(GetRecvQueue());
|
||||
} catch (const exception&) {
|
||||
Close();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json == NULL)
|
||||
if (message.get() == NULL)
|
||||
break;
|
||||
|
||||
JsonRpcMessage::Ptr msg = make_shared<JsonRpcMessage>();
|
||||
msg->SetJSON(json);
|
||||
NewMessageEventArgs::Ptr nea = make_shared<NewMessageEventArgs>();
|
||||
nea->Source = shared_from_this();
|
||||
nea->Message = msg;
|
||||
nea->Message = message;
|
||||
OnNewMessage(nea);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ struct I2_JSONRPC_API NewMessageEventArgs : public EventArgs
|
|||
typedef shared_ptr<NewMessageEventArgs> Ptr;
|
||||
typedef weak_ptr<NewMessageEventArgs> WeakPtr;
|
||||
|
||||
JsonRpcMessage::Ptr Message;
|
||||
Message::Ptr Message;
|
||||
};
|
||||
|
||||
class I2_JSONRPC_API JsonRpcClient : public TCPClient
|
||||
|
@ -21,7 +21,7 @@ public:
|
|||
typedef shared_ptr<JsonRpcClient> Ptr;
|
||||
typedef weak_ptr<JsonRpcClient> WeakPtr;
|
||||
|
||||
void SendMessage(JsonRpcMessage::Ptr message);
|
||||
void SendMessage(Message::Ptr message);
|
||||
|
||||
virtual void Start(void);
|
||||
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
#include "i2-jsonrpc.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
JsonRpcMessage::JsonRpcMessage(void)
|
||||
{
|
||||
m_JSON = NULL;
|
||||
}
|
||||
|
||||
JsonRpcMessage::~JsonRpcMessage(void)
|
||||
{
|
||||
cJSON_Delete(m_JSON);
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetJSON(cJSON *object)
|
||||
{
|
||||
cJSON_Delete(m_JSON);
|
||||
m_JSON = object;
|
||||
}
|
||||
|
||||
cJSON *JsonRpcMessage::GetJSON(void)
|
||||
{
|
||||
return m_JSON;
|
||||
}
|
||||
|
||||
void JsonRpcMessage::InitJson(void)
|
||||
{
|
||||
if (m_JSON == NULL)
|
||||
m_JSON = cJSON_CreateObject();
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetFieldObject(const char *field, cJSON *object)
|
||||
{
|
||||
if (m_JSON == NULL && object == NULL)
|
||||
return;
|
||||
|
||||
InitJson();
|
||||
|
||||
cJSON_DeleteItemFromObject(m_JSON, field);
|
||||
|
||||
if (object != NULL)
|
||||
cJSON_AddItemToObject(m_JSON, field, object);
|
||||
}
|
||||
|
||||
cJSON *JsonRpcMessage::GetFieldObject(const char *field)
|
||||
{
|
||||
if (m_JSON == NULL)
|
||||
return NULL;
|
||||
|
||||
return cJSON_GetObjectItem(m_JSON, field);
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetFieldString(const char *field, const string& value)
|
||||
{
|
||||
cJSON *object = cJSON_CreateString(value.c_str());
|
||||
SetFieldObject(field, object);
|
||||
}
|
||||
|
||||
string JsonRpcMessage::GetFieldString(const char *field)
|
||||
{
|
||||
cJSON *object = GetFieldObject(field);
|
||||
|
||||
if (object == NULL || object->type != cJSON_String)
|
||||
return string();
|
||||
|
||||
return string(object->valuestring);
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetVersion(const string& version)
|
||||
{
|
||||
SetFieldString("version", version);
|
||||
}
|
||||
|
||||
string JsonRpcMessage::GetVersion(void)
|
||||
{
|
||||
return GetFieldString("jsonrpc");
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetID(const string& id)
|
||||
{
|
||||
SetFieldString("id", id);
|
||||
}
|
||||
|
||||
string JsonRpcMessage::GetID(void)
|
||||
{
|
||||
return GetFieldString("id");
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetMethod(const string& method)
|
||||
{
|
||||
SetFieldString("method", method);
|
||||
}
|
||||
|
||||
string JsonRpcMessage::GetMethod(void)
|
||||
{
|
||||
return GetFieldString("method");
|
||||
}
|
||||
|
||||
void JsonRpcMessage::ClearParams(void)
|
||||
{
|
||||
SetFieldObject("params", NULL);
|
||||
}
|
||||
|
||||
cJSON *JsonRpcMessage::GetParams(void)
|
||||
{
|
||||
cJSON *object = GetFieldObject("params");
|
||||
|
||||
if (object == NULL) {
|
||||
object = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(m_JSON, "params", object);
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetParam(const string& name, const string& value)
|
||||
{
|
||||
}
|
||||
|
||||
cJSON *JsonRpcMessage::GetParam(const string& name)
|
||||
{
|
||||
cJSON *params = GetFieldObject("params");
|
||||
|
||||
if (params == NULL)
|
||||
return NULL;
|
||||
|
||||
return cJSON_GetObjectItem(params, name.c_str());
|
||||
}
|
||||
|
||||
bool JsonRpcMessage::GetParamString(const string name, string *value)
|
||||
{
|
||||
cJSON *param = GetParam(name);
|
||||
|
||||
if (param == NULL || param->type != cJSON_String)
|
||||
return false;
|
||||
|
||||
*value = param->valuestring;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void JsonRpcMessage::ClearResult(void)
|
||||
{
|
||||
SetFieldObject("result", NULL);
|
||||
}
|
||||
|
||||
cJSON *JsonRpcMessage::GetResult(void)
|
||||
{
|
||||
cJSON *object = GetFieldObject("result");
|
||||
|
||||
if (object == NULL) {
|
||||
object = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(m_JSON, "result", object);
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void JsonRpcMessage::SetError(const string& error)
|
||||
{
|
||||
SetFieldString("error", error);
|
||||
}
|
||||
|
||||
string JsonRpcMessage::GetError(void)
|
||||
{
|
||||
return GetFieldString("error");
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
#ifndef JSONRPCMESSAGE_H
|
||||
#define JSONRPCMESSAGE_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class I2_JSONRPC_API JsonRpcMessage : public Object
|
||||
{
|
||||
private:
|
||||
cJSON *m_JSON;
|
||||
|
||||
void InitJson(void);
|
||||
|
||||
void SetFieldString(const char *field, const string& value);
|
||||
string GetFieldString(const char *field);
|
||||
|
||||
void ClearField(const char *field);
|
||||
void SetFieldObject(const char *field, cJSON *object);
|
||||
cJSON *GetFieldObject(const char *field);
|
||||
|
||||
public:
|
||||
typedef shared_ptr<JsonRpcMessage> Ptr;
|
||||
typedef weak_ptr<JsonRpcMessage> WeakPtr;
|
||||
|
||||
JsonRpcMessage(void);
|
||||
~JsonRpcMessage(void);
|
||||
|
||||
void SetJSON(cJSON *object);
|
||||
cJSON *GetJSON(void);
|
||||
|
||||
void SetVersion(const string& version);
|
||||
string GetVersion(void);
|
||||
|
||||
void SetID(const string& id);
|
||||
string GetID(void);
|
||||
|
||||
void SetMethod(const string& method);
|
||||
string GetMethod(void);
|
||||
|
||||
void ClearParams(void);
|
||||
cJSON *GetParams(void);
|
||||
|
||||
void SetParam(const string& name, const string& value);
|
||||
cJSON *GetParam(const string& name);
|
||||
bool GetParamString(const string name, string *value);
|
||||
|
||||
void ClearResult();
|
||||
cJSON *GetResult(void);
|
||||
|
||||
void SetError(const string& error);
|
||||
string GetError(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* JSONRPCMESSAGE_H */
|
|
@ -0,0 +1,5 @@
|
|||
JsonRpcRequest : Message
|
||||
JsonRpc : string
|
||||
Method : string
|
||||
Params : Message
|
||||
ID : string
|
|
@ -0,0 +1,5 @@
|
|||
JsonRpcResponse : Message
|
||||
JsonRpc : string
|
||||
Result : string
|
||||
Error : string
|
||||
ID : string
|
|
@ -4,7 +4,7 @@
|
|||
using namespace icinga;
|
||||
|
||||
/* based on https://github.com/PeterScott/netstring-c/blob/master/netstring.c */
|
||||
cJSON *Netstring::ReadJSONFromFIFO(FIFO::Ptr fifo)
|
||||
Message::Ptr Netstring::ReadMessageFromFIFO(FIFO::Ptr fifo)
|
||||
{
|
||||
size_t buffer_length = fifo->GetSize();
|
||||
char *buffer = (char *)fifo->GetReadBuffer();
|
||||
|
@ -53,18 +53,19 @@ cJSON *Netstring::ReadJSONFromFIFO(FIFO::Ptr fifo)
|
|||
/* remove the data from the fifo */
|
||||
fifo->Read(NULL, i + len + 1);
|
||||
|
||||
return object;
|
||||
return make_shared<Message>(object);
|
||||
}
|
||||
|
||||
void Netstring::WriteJSONToFIFO(FIFO::Ptr fifo, cJSON *object)
|
||||
void Netstring::WriteMessageToFIFO(FIFO::Ptr fifo, Message::Ptr message)
|
||||
{
|
||||
char *json;
|
||||
shared_ptr<cJSON> object = message->GetJson();
|
||||
size_t len;
|
||||
|
||||
#ifdef _DEBUG
|
||||
json = cJSON_Print(object);
|
||||
json = cJSON_Print(object.get());
|
||||
#else /* _DEBUG */
|
||||
json = cJSON_PrintUnformatted(object);
|
||||
json = cJSON_PrintUnformatted(object.get());
|
||||
#endif /* _DEBUG */
|
||||
|
||||
len = strlen(json);
|
||||
|
|
|
@ -14,8 +14,8 @@ public:
|
|||
typedef shared_ptr<Netstring> Ptr;
|
||||
typedef weak_ptr<Netstring> WeakPtr;
|
||||
|
||||
static cJSON *ReadJSONFromFIFO(FIFO::Ptr fifo);
|
||||
static void WriteJSONToFIFO(FIFO::Ptr fifo, cJSON *object);
|
||||
static Message::Ptr ReadMessageFromFIFO(FIFO::Ptr fifo);
|
||||
static void WriteMessageToFIFO(FIFO::Ptr fifo, Message::Ptr message);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void trim(string& str, const char *whitespace = "\r\n\t ")
|
||||
{
|
||||
string::size_type pos;
|
||||
|
||||
pos = str.find_first_not_of(whitespace);
|
||||
if (pos != string::npos)
|
||||
str.erase(0, pos);
|
||||
|
||||
pos = str.find_last_not_of(whitespace);
|
||||
if (pos != string::npos)
|
||||
str.erase(pos + 1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
cerr << "Syntax: " << argv[0] << " <file.message>" << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char *pos;
|
||||
pos = strrchr(argv[1], '.');
|
||||
|
||||
if (pos == NULL || strcmp(pos, ".message") != 0) {
|
||||
cerr << "Input filename must have the '.message' extension." << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char *headername, *implname;
|
||||
headername = strdup(argv[1]);
|
||||
strcpy(&(headername[pos - argv[1]]), ".h");
|
||||
|
||||
implname = strdup(argv[1]);
|
||||
strcpy(&(implname[pos - argv[1]]), ".cpp");
|
||||
|
||||
fstream inputfp, headerfp, implfp;
|
||||
|
||||
inputfp.open(argv[1], fstream::in);
|
||||
headerfp.open(headername, fstream::out | fstream::trunc);
|
||||
implfp.open(implname, fstream::out | fstream::trunc);
|
||||
|
||||
string line;
|
||||
string klass, klassupper, base;
|
||||
bool hasclass = false;
|
||||
|
||||
while (true) {
|
||||
getline(inputfp, line);
|
||||
|
||||
if (inputfp.fail())
|
||||
break;
|
||||
|
||||
if (!hasclass) {
|
||||
string::size_type index = line.find(':');
|
||||
|
||||
if (index == string::npos) {
|
||||
cerr << "Must specify class and base name." << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
klass = line.substr(0, index);
|
||||
trim(klass);
|
||||
|
||||
klassupper = klass;
|
||||
transform(klassupper.begin(), klassupper.end(), klassupper.begin(), toupper);
|
||||
|
||||
base = line.substr(index + 1);
|
||||
trim(base);
|
||||
|
||||
cout << "Class: '" << klass << "' (inherits from: '" << base << "')" << endl;
|
||||
|
||||
headerfp << "#ifndef " << klassupper << "_H" << endl
|
||||
<< "#define " << klassupper << "_H" << endl
|
||||
<< endl
|
||||
<< "namespace icinga" << endl
|
||||
<< "{" << endl
|
||||
<< endl
|
||||
<< "class " << klass << " : public " << base << endl
|
||||
<< "{" << endl
|
||||
<< endl
|
||||
<< "public:" << endl
|
||||
<< "\ttypedef shared_ptr<" << klass << "> Ptr;" << endl
|
||||
<< "\ttypedef weak_ptr<" << klass << "> WeakPtr;" << endl
|
||||
<< endl
|
||||
<< "\t" << klass << "(void) : " << base << "() { }" << endl
|
||||
<< "\t" << klass << "(const Message::Ptr& message) : " << base << "(message) { }" << endl
|
||||
<< endl;
|
||||
|
||||
implfp << "#include \"i2-jsonrpc.h\"" << endl
|
||||
<< "#include \"" << headername << "\"" << endl
|
||||
<< endl
|
||||
<< "using namespace icinga;" << endl
|
||||
<< endl;
|
||||
|
||||
hasclass = true;
|
||||
} else {
|
||||
string::size_type index = line.find(':');
|
||||
|
||||
if (index == string::npos) {
|
||||
cerr << "Must specify type and property name." << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
string prop = line.substr(0, index);
|
||||
trim(prop);
|
||||
|
||||
string type = line.substr(index + 1);
|
||||
trim(type);
|
||||
|
||||
string typeaccessor = type;
|
||||
typeaccessor[0] = toupper(typeaccessor[0]);
|
||||
|
||||
string rawtype = type;
|
||||
|
||||
/* assume it's a reference type if we don't know the type */
|
||||
if (type != "int" && type != "string") {
|
||||
type = type + "::Ptr";
|
||||
typeaccessor = "Message";
|
||||
}
|
||||
|
||||
cout << "Property: '" << prop << "' (Type: '" << type << "')" << endl;
|
||||
|
||||
headerfp << endl
|
||||
<< "\tbool Get" << prop << "(" << type << " *value);" << endl
|
||||
<< "\tvoid Set" << prop << "(const " << type << "& value);" << endl;
|
||||
|
||||
implfp << "bool " << klass << "::Get" << prop << "(" << type << " *value)" << endl
|
||||
<< "{" << endl;
|
||||
|
||||
if (typeaccessor == "Message") {
|
||||
implfp << "\tMessage::Ptr message;" << endl
|
||||
<< endl
|
||||
<< "\tif (!GetProperty" << typeaccessor << "(\"" << prop << "\", &message))" << endl
|
||||
<< "\treturn false;" << endl
|
||||
<< endl
|
||||
<< "\t*value = message->Cast<" + rawtype + ">();" << endl
|
||||
<< "return true;" << endl
|
||||
<< endl;
|
||||
} else {
|
||||
implfp << "\treturn GetProperty" << typeaccessor << "(\"" << prop << "\", value);" << endl;
|
||||
}
|
||||
|
||||
implfp << "}" << endl
|
||||
<< endl;
|
||||
|
||||
implfp << "void " << klass << "::Set" << prop << "(const " << type << "& value)" << endl
|
||||
<< "{" << endl
|
||||
<< "\tSetProperty" << typeaccessor << "(\"" << prop << "\", value);" << endl
|
||||
<< "}" << endl
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
headerfp << endl
|
||||
<< "};" << endl
|
||||
<< endl
|
||||
<< "}" << endl
|
||||
<< endl
|
||||
<< "#endif /* " << klassupper << "_H */" << endl;
|
||||
|
||||
inputfp.close();
|
||||
headerfp.close();
|
||||
implfp.close();
|
||||
|
||||
free(headername);
|
||||
free(implname);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4F00EE82-B829-4872-B8F0-C1A8D86C94B4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>msgc</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="msgc.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue