From ce52eeb9ee3732aa4c88cfd2c70feea8e911e1ff Mon Sep 17 00:00:00 2001 From: deva Date: Wed, 17 Feb 2010 14:43:14 +0000 Subject: Use libartefact for pentominos data retrieval. --- server/configure.in | 4 +- server/src/Makefile.am | 21 +-- server/src/queryhandlerpentominos.cc | 240 +++++++---------------------------- server/src/queryhandlerpentominos.h | 12 +- server/src/queryparser.cc | 168 ------------------------ server/src/queryparser.h | 81 ------------ server/src/server.cc | 23 ++-- 7 files changed, 67 insertions(+), 482 deletions(-) delete mode 100644 server/src/queryparser.cc delete mode 100644 server/src/queryparser.h (limited to 'server') diff --git a/server/configure.in b/server/configure.in index 7449594..835f109 100644 --- a/server/configure.in +++ b/server/configure.in @@ -126,9 +126,9 @@ dnl ====================== PKG_CHECK_MODULES(CONFIG, libconfig++ >= 1.0.1) dnl ====================== -dnl Check for libmicrohttpd +dnl Check for libartefact dnl ====================== -PKG_CHECK_MODULES(HTTPD, libmicrohttpd >= 0.4.4) +PKG_CHECK_MODULES(ATF, libartefact >= 0.1.0) dnl ====================== dnl Check for eXpat library diff --git a/server/src/Makefile.am b/server/src/Makefile.am index 9af183f..f269db8 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -1,9 +1,11 @@ bin_PROGRAMS = pracrod macrotool -pracrod_LDADD = $(LD_EFENCE) $(PQXX_LIBS) $(CONFIG_LIBS) $(LUA_LIBS) $(HTTPD_LIBS) -lpthread +pracrod_LDADD = $(LD_EFENCE) $(PQXX_LIBS) $(CONFIG_LIBS) \ + $(LUA_LIBS) $(HTTPD_LIBS) -lpthread $(ATF_LIBS) -pracrod_CXXFLAGS = $(PQXX_CXXFLAGS) $(CONFIG_CXXFLAGS) $(LUA_CXXFLAGS) $(HTTPD_CFLAGS) +pracrod_CXXFLAGS = $(PQXX_CXXFLAGS) $(CONFIG_CXXFLAGS) \ + $(LUA_CXXFLAGS) $(HTTPD_CFLAGS) $(ATF_CFLAGS) pracrod_SOURCES = \ pracrod.cc \ @@ -15,7 +17,6 @@ pracrod_SOURCES = \ exception.cc \ queryhandlerpentominos.cc \ queryhandlerpracro.cc \ - queryparser.cc \ journal_commit.cc \ log.cc \ luaquerymapper.cc \ @@ -78,7 +79,6 @@ EXTRA_DIST = \ queryhandler.h \ queryhandlerpentominos.h \ queryhandlerpracro.h \ - queryparser.h \ journal_commit.h \ log.h \ luaquerymapper.h \ @@ -126,7 +126,6 @@ TESTFILES = \ test_macrolist \ test_queryhandlerpentominos \ test_queryhandlerpracro \ - test_queryparser \ test_luaquerymapper \ test_templateparser \ test_server \ @@ -242,29 +241,20 @@ test_versionstr: $(TEST_VERSIONSTR_FILES) TEST_QUERYHANDLERPENTOMINOS_FILES = \ queryhandlerpentominos.cc \ tcpsocket.cc \ - queryparser.cc \ $(PARSERFILES) \ $(BASICFILES) test_queryhandlerpentominos: $(TEST_QUERYHANDLERPENTOMINOS_FILES) - @../../tools/test $(TEST_QUERYHANDLERPENTOMINOS_FILES) $(PARSERFLAGS) $(BASICFLAGS) + @../../tools/test $(TEST_QUERYHANDLERPENTOMINOS_FILES) $(PARSERFLAGS) $(BASICFLAGS) $(ATF_CFLAGS) $(ATF_LIBS) TEST_QUERYHANDLERPRACRO_FILES = \ queryhandlerpracro.cc \ tcpsocket.cc \ - queryparser.cc \ $(DBFILES) \ $(PARSERFILES) \ $(BASICFILES) test_queryhandlerpracro: $(TEST_QUERYHANDLERPRACRO_FILES) @../../tools/test $(TEST_QUERYHANDLERPRACRO_FILES) $(DBFLAGS) $(PARSERFLAGS) $(BASICFLAGS) -TEST_QUERYPARSER_FILES = \ - queryparser.cc \ - $(BASICFILES) \ - $(PARSERFILES) -test_queryparser: $(TEST_QUERYPARSER_FILES) - @../../tools/test $(TEST_QUERYPARSER_FILES) $(BASICFLAGS) $(PARSERFLAGS) - TEST_LUAQUERMAPPER_FILES = \ luaquerymapper.cc \ $(BASICFILES) @@ -290,7 +280,6 @@ TEST_SERVER_FILES = \ templateparser.cc \ templatelist.cc \ templateheaderparser.cc \ - queryparser.cc \ queryhandlerpentominos.cc \ journal_commit.cc \ macrolist.cc \ diff --git a/server/src/queryhandlerpentominos.cc b/server/src/queryhandlerpentominos.cc index 62a742f..33609cc 100644 --- a/server/src/queryhandlerpentominos.cc +++ b/server/src/queryhandlerpentominos.cc @@ -28,232 +28,82 @@ #include "debug.h" -#include +#include "configuration.h" -// For time -#include - -#include -#include -#include - -// For getpid -#include -#include - -// For time -#include - -// For strerror and errno -#include - -// For socket and friends -#include -#include -#include -#include - -// For ioctl -#include - -#include "queryparser.h" - -typedef struct { - in_addr_t ip; - time_t time; - pid_t pid; - unsigned short int count; -} UID; - -#define SIOCGIFCONF 0x8912 // get iface list - -static in_addr_t getIP(const char *interface) +QueryHandlerPentominos::QueryHandlerPentominos(std::string cpr) + : QueryHandler() { - in_addr_t ret = 0; - int numreqs = 30, sd, n; - struct ifconf ifc; - struct ifreq *ifr; - struct in_addr *ia; - - sd = socket(AF_INET, SOCK_STREAM, 0); - if(sd == -1) { - // throw Pentominos::UIDCouldNotConnectException(strerror(errno)); - } - - ifc.ifc_buf = NULL; - ifc.ifc_len = sizeof(struct ifreq) * numreqs; - - ifc.ifc_buf = (char*)malloc(ifc.ifc_len); - if(ifc.ifc_buf == NULL) { - // throw Pentominos::UIDOutOfMemoryException(); - } + this->cpr = cpr; - if (ioctl(sd, SIOCGIFCONF, &ifc) < 0) { - // throw Pentominos::UIDInterfaceListException(strerror(errno)); - } + atfh = atf_init(); - ifr = ifc.ifc_req; - for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { - ia = (struct in_addr *)((ifr->ifr_ifru.ifru_addr.sa_data)+2); - if(!strcmp(ifr->ifr_ifrn.ifrn_name, interface)) { - ret = *(in_addr_t*)ia; - } - ifr++; - } + bool use_https = false; + atfc = atf_connect(atfh, Conf::pentominos_addr.c_str(), + Conf::pentominos_port, use_https); - if(!ret) { // Still no interface... We're fucked! - // throw Pentominos::UIDInterfaceException(interface); - } - - free(ifc.ifc_buf); - return ret; } - -static unsigned short counter = 0; -static unsigned short getCounter() +QueryHandlerPentominos::~QueryHandlerPentominos() { - return counter++; + atf_disconnect(atfc); + atf_close(atfh); } -static UID uid = {0,0,0,0}; -static std::string getUID(const char *interface) +static QueryResult node2result(atf_result_node_t *node, time_t timestamp) { - if(!uid.ip) uid.ip = getIP(interface); - - time_t t = time(NULL); - if(uid.time != t) counter = 0; // If time differes, reset the counter - uid.time = t; // We need this value every time. - - if(!uid.pid) uid.pid = getpid(); - - uid.count = getCounter(); + QueryResult rnode; + rnode.timestamp = timestamp; + rnode.source = "pentominos"; + + if(!node) return rnode; + + struct _atf_result_node_t *child = node->child; + while(child) { + if(child->value == NULL) { + rnode.groups[child->name] = node2result(child, timestamp); + } else { + rnode.values[child->name] = child->value; + } + child = child->next; + } - char buf[32]; - sprintf(buf, "%08x%08x%04x%04x", uid.ip, (unsigned int)uid.time, uid.pid, uid.count); - return std::string(buf); -} - - -QueryHandlerPentominos::QueryHandlerPentominos(TCPSocket &_socket, std::string cpr) - : QueryHandler(), socket(_socket) -{ - this->cpr = cpr; + return rnode; } QueryResult QueryHandlerPentominos::exec(Query &query) { - time_t timestamp = time(NULL); - std::string uid = getUID("eth0"); - - char buf[512]; - char header[] = - "\n" - "\n"; -#ifndef WITHOUT_PENTOMINOS - socket.write(header, strlen(header)); -#endif/*WITHOUT_PENTOMINOS*/ - - PRACRO_DEBUG(queryhandler, "%s", header); - - sprintf(buf, " \n", - cpr.c_str(), - "pracro", -#ifndef WITHOUT_PENTOMINOS - socket.srcaddr().c_str(), - socket.dstaddr().c_str(), -#else - "127.0.0.1", - "127.0.0.1", -#endif/*WITHOUT_PENTOMINOS*/ - (unsigned int)timestamp, - uid.c_str()); -#ifndef WITHOUT_PENTOMINOS - socket.write(buf, strlen(buf)); -#endif/*WITHOUT_PENTOMINOS*/ + atf_transaction_t* atft = atf_new_transaction(atfc, cpr.c_str()); - PRACRO_DEBUG(queryhandler, "%s", buf); + atf_id id = atf_add_query(atft, query.attributes["class"].c_str(), 0, "xml"); - sprintf(buf, " \n", - query.attributes["class"].c_str(), - query.attributes["class"].c_str()); - -#ifndef WITHOUT_PENTOMINOS - socket.write(buf, strlen(buf)); -#endif/*WITHOUT_PENTOMINOS*/ + atf_reply_t *reply = atf_commit(atft); - PRACRO_DEBUG(queryhandler, "%s", buf); + atf_status_t status = atf_get_reply_status(reply, id); + if(status != ATF_STATUS_OK) { return QueryResult(); } + + time_t timestamp = atf_get_reply_timestamp(reply, id); - sprintf(buf, ""); + atf_result_node_t *root = atf_get_result_node(reply, id); -#ifndef WITHOUT_PENTOMINOS - socket.write(buf, strlen(buf)); -#endif/*WITHOUT_PENTOMINOS*/ + QueryResult rroot; + rroot.timestamp = timestamp; + rroot.source = "pentominos"; - PRACRO_DEBUG(queryhandler, "%s", buf); + QueryResult result = node2result(root, timestamp); + if(root) rroot.groups[query.attributes["class"]] = result; - QueryResult result; - -#ifndef WITHOUT_PENTOMINOS - QueryParser parser; + atf_free_result_node(root); + atf_free_reply(reply); + atf_free_transaction(atft); - ssize_t size; - - // Read until we've got the entire result. - while((size = socket.read(buf, sizeof(buf))) > 0) { - // fwrite(buf, size, 1, stdout); fflush(stdout); - if(parser.parse(buf, size)) break; - } - - result = parser.result; -#endif/*WITHOUT_PENTOMINOS*/ - - PRACRO_INFO(queryhandler, "Done handling query\n"); - - result.print(); - - return result; + return rroot; } #ifdef TEST_QUERYHANDLERPENTOMINOS int main() { -#ifdef WITHOUT_PENTOMINOS - printf("The project need to be configured for use of Pentominos in order to run this test.\n"); return 1; -#endif/*WITHOUT_PENTOMINOS*/ - - TCPSocket s; - try { - s.connect("localhost", 11108); - } catch(Exception &e) { - printf("ERROR: %s\n", e.what()); - printf("A running instance of the artefact server in needed on localhost, port 11108 in order for this test to run.\n"); - return 1; - } - - QueryHandlerPentominos qh(s, "2003791613"); - - Query q1; - q1.attributes["device_id"] = "lensmeter"; - q1.attributes["device_type"] = "lensmeter"; - QueryResult res = qh.exec(q1); - res.print(); - - return 0; } #endif/*TEST_QUERYHANDLERPENTOMINOS*/ diff --git a/server/src/queryhandlerpentominos.h b/server/src/queryhandlerpentominos.h index 9c56d07..53b01ad 100644 --- a/server/src/queryhandlerpentominos.h +++ b/server/src/queryhandlerpentominos.h @@ -29,26 +29,28 @@ #include "queryhandler.h" -#include "tcpsocket.h" #include "template.h" #include "queryresult.h" -#include #include +#include + /** * This class handles the query of external data. */ class QueryHandlerPentominos : public QueryHandler { public: - QueryHandlerPentominos(TCPSocket &socket, std::string cpr); - ~QueryHandlerPentominos() {} + QueryHandlerPentominos(std::string cpr); + ~QueryHandlerPentominos(); // Execute all queries. QueryResult exec(Query &query); private: - TCPSocket &socket; + atf_handle_t *atfh; + atf_connection_t *atfc; + std::string cpr; }; diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc deleted file mode 100644 index db562ae..0000000 --- a/server/src/queryparser.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - * queryparser.cc - * - * Tue May 6 17:02:37 CEST 2008 - * Copyright 2008 Bent Bisballe Nyeng - * deva@aasimon.org - ****************************************************************************/ - -/* - * This file is part of Pracro. - * - * Pracro is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Pracro is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Pracro; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ -#include "queryparser.h" - -QueryParser::QueryParser() -{ - this->timestamp = 0; - - p = 0; - stack.push_back(&result); -} - -void QueryParser::startTag(std::string name, std::map< std::string, std::string> attributes) -{ - - if(name == "results") { - // What to do here!? - } - - if(name == "result") { - this->timestamp = atol(attributes["timestamp"].c_str()); - - QueryResult q; - q.source = "pentominos"; - q.timestamp = this->timestamp; - stack.back()->groups[attributes["class"]] = q; - stack.push_back(&stack.back()->groups[attributes["class"]]); - } - - if(name == "group") { - QueryResult q; - q.timestamp = this->timestamp; - stack.back()->groups[attributes["name"]] = q; - stack.push_back(&stack.back()->groups[attributes["name"]]); - } - - if(name == "value") { - stack.back()->values[attributes["name"]] = utf8.decode(attributes["value"]); - } - -} - -void QueryParser::endTag(std::string name) -{ - if(name == "group" || name == "result") stack.pop_back(); -} - -void QueryParser::parseError(const char *buf, size_t len, std::string error, int lineno) -{ - fprintf(stderr, "QueryParser error at line %d: %s\n", lineno, error.c_str()); - fprintf(stderr, "\tBuffer %u bytes: [", len); - if(fwrite(buf, len, 1, stderr) != len) {} - fprintf(stderr, "]\n"); - fflush(stderr); - - char *slineno; - if(asprintf(&slineno, " at line %d\n", lineno) != -1) { - throw Exception(error + slineno); - free(slineno); - } - -} - -#ifdef TEST_QUERYPARSER - -#include - -static char xml[] = - "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "\n" -; - -static char badxml[] = - "\n" - "\n" - "\n" -; - -static std::string loadresultstring(QueryResult &res, std::string group = "") -{ - std::string s; - - std::map< std::string, std::string >::iterator v = res.values.begin(); - while(v != res.values.end()) { - s += group + (*v).first + " = \"" + (*v).second + "\"\n"; - v++; - } - - std::map< std::string, QueryResult >::iterator g = res.groups.begin(); - while(g != res.groups.end()) { - s += group + (*g).first + " = {}\n"; - s += loadresultstring((*g).second, group + (*g).first + "."); - g++; - } - - return s; -} - -int main() -{ - // Parse something - { - QueryParser parser; - parser.parse(xml, strlen(xml)); - printf("%s\n", loadresultstring(parser.result).c_str()); - } - - // Parse something, and fail! - try { - QueryParser parser; - parser.parse(badxml, strlen(badxml)); - printf("%s\n", loadresultstring(parser.result).c_str()); - } catch(Exception &e) { - printf("ERROR: %s\n", e.what()); - goto weitergehen; - } - return 1; - weitergehen: - - return 0; -} - -#endif/*TEST_QUERYPARSER*/ diff --git a/server/src/queryparser.h b/server/src/queryparser.h deleted file mode 100644 index f901d2c..0000000 --- a/server/src/queryparser.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - * queryparser.h - * - * Tue May 6 17:02:36 CEST 2008 - * Copyright 2008 Bent Bisballe Nyeng - * deva@aasimon.org - ****************************************************************************/ - -/* - * This file is part of Pracro. - * - * Pracro is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Pracro is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Pracro; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ -#ifndef __PRACRO_QUERYPARSER_H__ -#define __PRACRO_QUERYPARSER_H__ - -#include "saxparser.h" - -#include -#include - -#include "queryresult.h" -#include "utf8.h" -#include "exception.h" - -/** - * This class parses xml entities into a QueryResult structure. - * Call the parent (SAXParser) method parse in order to actually parse something. - * If the parser fails (syntax error) it will throw an Exception. - * @see QueryResult result, in order to get the parsed data. - */ -class QueryParser : public SAXParser { -public: - /** - * Constructor. - */ - QueryParser(); - - /** - * The object will contain the result when the parsing is done. - */ - QueryResult result; - - /** - * Private parser callback. - */ - void startTag(std::string name, std::map< std::string, std::string> attributes); - - /** - * Private parser callback. - */ - void endTag(std::string name); - - /** - * Private parser callback. - */ - void parseError(const char *buf, size_t len, std::string error, int lineno); - -private: - // For read - int p; - std::string document; - time_t timestamp; - std::vector< QueryResult * > stack; - UTF8 utf8; -}; - -#endif/*__PRACRO_QUERYPARSER_H__*/ diff --git a/server/src/server.cc b/server/src/server.cc index f2be8a4..9c653f8 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -46,7 +46,6 @@ #include "queryhandlerpracro.h" #include "queryhandlerpentominos.h" -#include "queryparser.h" #include "luaquerymapper.h" #include "database.h" #include "widgetgenerator.h" @@ -116,7 +115,6 @@ static std::string handleCommits(Transaction *transaction, Database &db, static std::string handleRequest(Transaction *transaction, - TCPSocket &pentominos_socket, Database &db, JournalWriter &journalwriter, MacroList ¯olist, @@ -124,6 +122,9 @@ static std::string handleRequest(Transaction *transaction, { std::string answer; + // Reuse connection throughout entire template. + QueryHandlerPentominos qh(transaction->cpr); + Requests::iterator i = transaction->requests.begin(); while(i != transaction->requests.end()) { Request &request = *i; @@ -186,7 +187,7 @@ static std::string handleRequest(Transaction *transaction, LUAQueryMapper lqm; - //////////////////////// + //////////////////////// std::vector< Query >::iterator qi = m->queries.begin(); while(qi != m->queries.end()) { @@ -195,14 +196,12 @@ static std::string handleRequest(Transaction *transaction, if(service == "pentominos") { // Send the queries to Pentominos (if any) - QueryHandlerPentominos qh(pentominos_socket, transaction->cpr); - QueryResult queryresult = qh.exec(*qi); lqm.addQueryResult(queryresult); } if(service == "pracro") { - // Send the queries to Pentominos (if any) + // Send the queries to Pracro (if any) QueryHandlerPracro qh(db, transaction->cpr); QueryResult queryresult = qh.exec(*qi); @@ -261,7 +260,6 @@ static std::string handleRequest(Transaction *transaction, } static std::string handleTransaction(Transaction *transaction, - TCPSocket &pentominos_socket, Database &db, JournalWriter &journalwriter, MacroList ¯olist, @@ -279,7 +277,7 @@ static std::string handleTransaction(Transaction *transaction, } try { - answer += handleRequest(transaction, pentominos_socket, db, journalwriter, + answer += handleRequest(transaction, db, journalwriter, macrolist, templatelist); } catch( std::exception &e ) { PRACRO_ERR(server, "Request error: %s\n", e.what()); @@ -296,11 +294,6 @@ static std::string handleTransaction(Transaction *transaction, static void handleConnection(TCPSocket *socket) { - TCPSocket pentominos_socket; -#ifndef WITHOUT_PENTOMINOS - pentominos_socket.connect(Conf::pentominos_addr, Conf::pentominos_port); -#endif/*WITHOUT_PENTOMINOS*/ - Database db(Conf::database_backend, Conf::database_addr, "", Conf::database_user, Conf::database_passwd, ""); JournalWriter journalwriter(Conf::journal_commit_addr.c_str(), Conf::journal_commit_port); @@ -333,8 +326,8 @@ static void handleConnection(TCPSocket *socket) if(parser->parse(buf, size)) { PRACRO_DEBUG(server, "Got complete XML document %d bytes used, %d bytes in current buffer.\n", parser->usedBytes(), size); - socket->write(handleTransaction(transaction, pentominos_socket, - db, journalwriter, macrolist, templatelist)); + socket->write(handleTransaction(transaction, db, journalwriter, + macrolist, templatelist)); size = size - parser->usedBytes(); if(size) { strcpy(buf, buf + parser->usedBytes()); -- cgit v1.2.3