#include "conn.h"
#include "radlog.h"
+#include "stgpair.h"
#include "stg/json_parser.h"
#include "stg/json_generator.h"
struct ChannelConfig {
struct Error : std::runtime_error {
- Error(const std::string& message) : runtime_error(message) {}
+ explicit Error(const std::string& message) : runtime_error(message) {}
};
- ChannelConfig(std::string address);
+ explicit ChannelConfig(std::string address);
std::string transport;
std::string key;
std::map<std::string, Packet> packetCodes;
std::map<std::string, bool> resultCodes;
+std::map<std::string, int> returnCodes;
class PacketParser : public EnumParser<Packet>
{
}
};
+class ReturnCodeParser : public EnumParser<int>
+{
+ public:
+ ReturnCodeParser(NodeParser* next, int& returnCode, std::string& returnCodeStr)
+ : EnumParser(next, returnCode, returnCodeStr, returnCodes)
+ {
+ if (!returnCodes.empty())
+ return;
+ returnCodes["reject"] = STG_REJECT;
+ returnCodes["fail"] = STG_FAIL;
+ returnCodes["ok"] = STG_OK;
+ returnCodes["handled"] = STG_HANDLED;
+ returnCodes["invalid"] = STG_INVALID;
+ returnCodes["userlock"] = STG_USERLOCK;
+ returnCodes["notfound"] = STG_NOTFOUND;
+ returnCodes["noop"] = STG_NOOP;
+ returnCodes["updated"] = STG_UPDATED;
+ }
+};
+
class TopParser : public NodeParser
{
public:
TopParser(Callback callback, void* data)
: m_packet(PING),
m_result(false),
+ m_returnCode(STG_REJECT),
m_packetParser(this, m_packet, m_packetStr),
m_resultParser(this, m_result, m_resultStr),
+ m_returnCodeParser(this, m_returnCode, m_returnCodeStr),
m_replyParser(this, m_reply),
m_modifyParser(this, m_modify),
m_callback(callback), m_data(data)
return &m_replyParser;
else if (key == "modify")
return &m_modifyParser;
+ else if (key == "return_code")
+ return &m_returnCodeParser;
return this;
}
Packet packet() const { return m_packet; }
const std::string& resultStr() const { return m_resultStr; }
bool result() const { return m_result; }
+ const std::string& returnCodeStr() const { return m_returnCodeStr; }
+ int returnCode() const { return m_returnCode; }
const PairsParser::Pairs& reply() const { return m_reply; }
const PairsParser::Pairs& modify() const { return m_modify; }
Packet m_packet;
std::string m_resultStr;
bool m_result;
+ std::string m_returnCodeStr;
+ int m_returnCode;
PairsParser::Pairs m_reply;
PairsParser::Pairs m_modify;
PacketParser m_packetParser;
ResultParser m_resultParser;
+ ReturnCodeParser m_returnCodeParser;
PairsParser m_replyParser;
PairsParser m_modifyParser;
Packet packet() const { return m_topParser.packet(); }
const std::string& resultStr() const { return m_topParser.resultStr(); }
bool result() const { return m_topParser.result(); }
+ const std::string& returnCodeStr() const { return m_topParser.returnCodeStr(); }
+ int returnCode() const { return m_topParser.returnCode(); }
const PairsParser::Pairs& reply() const { return m_topParser.reply(); }
const PairsParser::Pairs& modify() const { return m_topParser.modify(); }
class PacketGen : public Gen
{
public:
- PacketGen(const std::string& type)
+ explicit PacketGen(const std::string& type)
: m_type(type)
{
m_gen.add("packet", m_type);
void runImpl();
+ bool start();
+
int connect();
int connectTCP();
int connectUNIX();
throw Error("Invalid port value.");
}
+Conn::Conn(const std::string& address, Callback callback, void* data)
+ : m_impl(new Impl(address, callback, data))
+{
+}
+
+Conn::~Conn()
+{
+}
+
+bool Conn::stop()
+{
+ return m_impl->stop();
+}
+
+bool Conn::connected() const
+{
+ return m_impl->connected();
+}
+
+bool Conn::request(REQUEST_TYPE type, const std::string& userName, const std::string& password, const PAIRS& pairs)
+{
+ return m_impl->request(type, userName, password, pairs);
+}
+
Conn::Impl::Impl(const std::string& address, Callback callback, void* data)
: m_config(address),
m_sock(connect()),
m_connected(true)
{
pthread_mutex_init(&m_mutex, NULL);
- int res = pthread_create(&m_thread, NULL, &Conn::Impl::run, this);
- if (res != 0)
- throw Error("Failed to create thread: " + std::string(strerror(errno)));
}
Conn::Impl::~Impl()
bool Conn::Impl::request(REQUEST_TYPE type, const std::string& userName, const std::string& password, const PAIRS& pairs)
{
+ if (!m_running)
+ if (!start())
+ return false;
MapGen map;
for (PAIRS::const_iterator it = pairs.begin(); it != pairs.end(); ++it)
map.add(it->first, new StringGen(it->second));
break;
}
+
if (!m_running)
break;
m_stopped = true;
}
+bool Conn::Impl::start()
+{
+ int res = pthread_create(&m_thread, NULL, &Conn::Impl::run, this);
+ if (res != 0)
+ return false;
+ return true;
+}
+
int Conn::Impl::connect()
{
if (m_config.transport == "tcp")
void Conn::Impl::processPing()
{
- RadLog("Got ping, sending pong.");
sendPong();
}
void Conn::Impl::processPong()
{
- RadLog("Got pong.");
m_lastActivity = time(NULL);
}
void Conn::Impl::processData()
{
RESULT data;
- RadLog("Got data.");
- for (PairsParser::Pairs::const_iterator it = m_parser.reply().begin(); it != m_parser.reply().end(); ++it)
- data.reply.push_back(std::make_pair(it->first, it->second));
- for (PairsParser::Pairs::const_iterator it = m_parser.modify().begin(); it != m_parser.modify().end(); ++it)
- data.modify.push_back(std::make_pair(it->first, it->second));
- m_callback(m_data, data, m_parser.result());
+ if (m_parser.result())
+ {
+ for (PairsParser::Pairs::const_iterator it = m_parser.reply().begin(); it != m_parser.reply().end(); ++it)
+ data.reply.push_back(std::make_pair(it->first, it->second));
+ for (PairsParser::Pairs::const_iterator it = m_parser.modify().begin(); it != m_parser.modify().end(); ++it)
+ data.modify.push_back(std::make_pair(it->first, it->second));
+ data.returnCode = STG_UPDATED;
+ }
+ else
+ data.returnCode = m_parser.returnCode();
+ m_callback(m_data, data);
}
bool Conn::Impl::sendPing()
bool Conn::Impl::write(void* data, const char* buf, size_t size)
{
- RadLog("Sending JSON:");
std::string json(buf, size);
- RadLog("%s", json.c_str());
+ RadLog("Sending JSON: %s", json.c_str());
Conn::Impl& impl = *static_cast<Conn::Impl*>(data);
while (size > 0)
{