From 5d56065e93168ddf8efacecbc606934490ac858d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Jaworski?= Date: Thu, 10 Apr 2014 10:35:23 +0200 Subject: [PATCH] concordia-server Former-commit-id: d6738a8d8b0c9482ef5a7416af5b732422e37dbe --- concordia-server-starter/CMakeLists.txt | 21 ++++ .../concordia_server_starter.cpp | 99 +++++++++++++++++++ concordia-server/CMakeLists.txt | 25 +++++ concordia-server/TODO.txt | 1 + concordia-server/compilation.dox | 61 ++++++++++++ concordia-server/concordia_server.cpp | 62 ++++++++++++ concordia-server/concordia_server.hpp | 30 ++++++ concordia-server/main.dox | 12 +++ concordia-server/running.dox | 32 ++++++ concordia-server/t/CMakeLists.txt | 6 ++ concordia-server/t/test_concordia.cpp | 19 ++++ concordia-server/t/test_concordia_config.cpp | 52 ++++++++++ concordia-server/technical.dox | 28 ++++++ concordia-server/test.html | 7 ++ 14 files changed, 455 insertions(+) create mode 100644 concordia-server-starter/CMakeLists.txt create mode 100644 concordia-server-starter/concordia_server_starter.cpp create mode 100644 concordia-server/CMakeLists.txt create mode 100644 concordia-server/TODO.txt create mode 100644 concordia-server/compilation.dox create mode 100644 concordia-server/concordia_server.cpp create mode 100644 concordia-server/concordia_server.hpp create mode 100644 concordia-server/main.dox create mode 100644 concordia-server/running.dox create mode 100644 concordia-server/t/CMakeLists.txt create mode 100644 concordia-server/t/test_concordia.cpp create mode 100644 concordia-server/t/test_concordia_config.cpp create mode 100644 concordia-server/technical.dox create mode 100644 concordia-server/test.html diff --git a/concordia-server-starter/CMakeLists.txt b/concordia-server-starter/CMakeLists.txt new file mode 100644 index 0000000..4546796 --- /dev/null +++ b/concordia-server-starter/CMakeLists.txt @@ -0,0 +1,21 @@ + +add_executable(concordia-server-starter concordia_server_starter.cpp) + +target_link_libraries(concordia-server-starter concordia-server concordia ${Boost_LIBRARIES} ${FCGIPP_LIB} ${FCGI_LIB} ${LIBCONFIG_LIB}) + +if (WITH_RE2) + target_link_libraries(concordia-server-starter re2) + if (WITH_PCRE) + target_link_libraries(concordia-server-starter pcrecpp) + endif(WITH_PCRE) +else(WITH_RE2) + if (WITH_PCRE) + target_link_libraries(concordia-server-starter pcrecpp) + endif(WITH_PCRE) +endif(WITH_RE2) + +# ===================================== + +install(TARGETS concordia-server-starter DESTINATION bin/) + + diff --git a/concordia-server-starter/concordia_server_starter.cpp b/concordia-server-starter/concordia_server_starter.cpp new file mode 100644 index 0000000..3fa83d0 --- /dev/null +++ b/concordia-server-starter/concordia_server_starter.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "concordia-server/concordia_server.hpp" + +using namespace std; + +static const unsigned long STDIN_MAX = 1000000; + +static long gstdin(FCGX_Request * request, char ** content) +{ + char * clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp); + unsigned long clen = STDIN_MAX; + + if (clenstr) + { + clen = strtol(clenstr, &clenstr, 10); + if (*clenstr) + { + cerr << "can't parse \"CONTENT_LENGTH=" + << FCGX_GetParam("CONTENT_LENGTH", request->envp) + << "\"\n"; + clen = STDIN_MAX; + } + + // *always* put a cap on the amount of data that will be read + if (clen > STDIN_MAX) clen = STDIN_MAX; + + *content = new char[clen]; + + cin.read(*content, clen); + clen = cin.gcount(); + } + else + { + // *never* read stdin when CONTENT_LENGTH is missing or unparsable + *content = 0; + clen = 0; + } + + // Chew up any remaining stdin - this shouldn't be necessary + // but is because mod_fastcgi doesn't handle it correctly. + + // ignore() doesn't set the eof bit in some versions of glibc++ + // so use gcount() instead of eof()... + do cin.ignore(1024); while (cin.gcount() == 1024); + + return clen; +} + +int main(int argc, char** argv) { + + // Backup the stdio streambufs + streambuf * cin_streambuf = cin.rdbuf(); + streambuf * cout_streambuf = cout.rdbuf(); + streambuf * cerr_streambuf = cerr.rdbuf(); + + ConcordiaServer concordiaServer("concordia.cfg"); + + FCGX_Request request; + + FCGX_Init(); + FCGX_InitRequest(&request, 0, 0); + + while (FCGX_Accept_r(&request) == 0) { + fcgi_streambuf cin_fcgi_streambuf(request.in); + fcgi_streambuf cout_fcgi_streambuf(request.out); + fcgi_streambuf cerr_fcgi_streambuf(request.err); + + cin.rdbuf(&cin_fcgi_streambuf); + cout.rdbuf(&cout_fcgi_streambuf); + cerr.rdbuf(&cerr_fcgi_streambuf); + + + char * content; + unsigned long clen = gstdin(&request, &content); + + string requestString(content); + + //TODO passing unicode strings + //boost::replace_all(requestString, "+", " "); + + cout << concordiaServer.handleRequest(requestString); + + // Note: the fcgi_streambuf destructor will auto flush + } + + // restore stdio streambufs + cin.rdbuf(cin_streambuf); + cout.rdbuf(cout_streambuf); + cerr.rdbuf(cerr_streambuf); + + return 0; +} diff --git a/concordia-server/CMakeLists.txt b/concordia-server/CMakeLists.txt new file mode 100644 index 0000000..2cdd220 --- /dev/null +++ b/concordia-server/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library(concordia-server SHARED + concordia_server.cpp + ) + +add_subdirectory(t) +# ===================================== + +install(TARGETS concordia-server DESTINATION lib/) +install(FILES concordia_server.hpp DESTINATION include/concordia-server/) + +target_link_libraries(concordia-server log4cpp) +target_link_libraries(concordia-server ${LIBSTEMMER_LIB}) +target_link_libraries(concordia-server ${Boost_LIBRARIES}) + +if (WITH_RE2) + target_link_libraries(concordia-server re2) + if (WITH_PCRE) + target_link_libraries(concordia-server pcrecpp) + endif(WITH_PCRE) +else(WITH_RE2) + if (WITH_PCRE) + target_link_libraries(concordia-server pcrecpp) + endif(WITH_PCRE) +endif(WITH_RE2) + diff --git a/concordia-server/TODO.txt b/concordia-server/TODO.txt new file mode 100644 index 0000000..f28f475 --- /dev/null +++ b/concordia-server/TODO.txt @@ -0,0 +1 @@ +use the echo.cpp source as an example for concordia-server-starter. It works with the up-to-date version of test.html (the one that specifies UTF-8 as character encoding in the
) diff --git a/concordia-server/compilation.dox b/concordia-server/compilation.dox new file mode 100644 index 0000000..b759082 --- /dev/null +++ b/concordia-server/compilation.dox @@ -0,0 +1,61 @@ +/** \page compilation Concordia Installation & Build Manual + +This file describes how to compile, build +and install Concordia library. + +\section compilation1 Requirements + +- cmake +- Boost library +- Log4cpp +- libstemmer (Snowball stemming library) +- (optional) Doxygen + +\subsection compilation1_1 Boost Ubuntu installation + +sudo apt-get install libboost-dev libboost-serialization-dev libboost-test-dev libboost-filesystem-dev libboost-system-de libboost-program-options-dev libboost-iostreams-dev + +\subsection compilation1_2 Log4cpp Ubuntu installation + +sudo apt-get install liblog4cpp5-dev + +\subsection compilation1_3 Libconfig Ubuntu installation + +sudo apt-get install libconfig++-dev +sudo apt-get install libconfig-dev + +\subsection compilation1_4 Libstemmer Ubuntu installation + +sudo apt-get install libstemmer-dev + +\subsection compilation1_5 Perl-compatible regular expressions (PCRE) Ubuntu installation + +sudo apt-get install libpcre3-dev + +\subsection compilation1_6 Doxygen Ubuntu installation + +sudo apt-get install doxygen + +\section compilation2 Build & installation procedure + +mkdir build
+cd build
+../cmake.sh
+make
+make test
+make install + +\section compilation3 Documentation + +If Doxygen is available, a successful compilation generates documentation data in three +formats in the build/doc directory. + +The man files in doc/man will be installed during installation. Open doc/html/index.html for +a HTML version of the same documentation. The latex directory contains uncompiled latex +files. To generate a single pdf file run + +cd doc/latex +make + +This should generate a single file called refman.pdf in the same directory. +*/ diff --git a/concordia-server/concordia_server.cpp b/concordia-server/concordia_server.cpp new file mode 100644 index 0000000..2628ac3 --- /dev/null +++ b/concordia-server/concordia_server.cpp @@ -0,0 +1,62 @@ +#include "concordia-server/concordia_server.hpp" + +#include +#include +#include +#include +#include + + +ConcordiaServer::ConcordiaServer(const std::string & configFilePath) + throw(ConcordiaException) { + _concordia = boost::shared_ptr ( + new Concordia(configFilePath)); + +} + +ConcordiaServer::~ConcordiaServer() { +} + +string ConcordiaServer::handleRequest(string & requestString) { + stringstream ss; + try { + ss << "Content-type: text/html\r\n" + << "\r\n" + << "\n" + << " \n" + << " Hello, World!\n" + << " \n" + << " \n" + << "

Hello, World!

\n" + << " The concordia version is: "<< _concordia->getVersion() << "\n" + << "

Input data:

\n" + << requestString; + + ss << "

Adding content as example:

\n"; + + Example example1(requestString, 0); + Example example2("Ala ma kota", 1); + Example example3("Marysia nie ma kota chyba", 2); + _concordia->addExample(example1); + _concordia->addExample(example2); + _concordia->addExample(example3); + + _concordia->refreshSAfromRAM(); + + ss << "

Searching ma kota:

\n"; + boost::ptr_vector result = + _concordia->simpleSearch("ma kota"); + BOOST_FOREACH(SubstringOccurence occurence, result) { + ss << "\t\tfound match in sentence number: " + << occurence.getId() << "

"; + } + ss << " \n" + << "\n"; + + } catch (ConcordiaException & e) { + ss << "

Concordia error:" << e.what() << "

"; + + } + return ss.str(); + +} diff --git a/concordia-server/concordia_server.hpp b/concordia-server/concordia_server.hpp new file mode 100644 index 0000000..ffe8b06 --- /dev/null +++ b/concordia-server/concordia_server.hpp @@ -0,0 +1,30 @@ +#ifndef CONCORDIA_SERVER_HDR +#define CONCORDIA_SERVER_HDR + +#include +#include +#include +#include + + +using namespace std; + +class ConcordiaServer { +public: + /*! Constructor. + \param configFilePath path to the Concordia configuration file + \throws ConcordiaException + */ + explicit ConcordiaServer(const std::string & configFilePath) + throw(ConcordiaException); + /*! Destructor. + */ + virtual ~ConcordiaServer(); + + string handleRequest(string & requestString); + +private: + boost::shared_ptr _concordia; +}; + +#endif diff --git a/concordia-server/main.dox b/concordia-server/main.dox new file mode 100644 index 0000000..0ecfb71 --- /dev/null +++ b/concordia-server/main.dox @@ -0,0 +1,12 @@ +/** \mainpage Introduction + +\section main_1 Concordia - Tool for concordance search in CAT + + +\section main_2 Overview + +- \subpage compilation This chapter contains instructions to compile, install and run Concordia. +- \subpage running The methods of making use of the Concordia library are described in this chapter. +- \subpage technical In this chapter technical information about unit tests, project resources and code style is provided. + +*/ diff --git a/concordia-server/running.dox b/concordia-server/running.dox new file mode 100644 index 0000000..83f9aa2 --- /dev/null +++ b/concordia-server/running.dox @@ -0,0 +1,32 @@ +/** \page running Running the Concordia library + +\section running1 Programmatical use of the library + +The main access point to the functionalities of the library is the Concordia class. An example programmatical use of the class is shown below: + +\verbatim +snippet +\endverbatim + +\section running2 The concordia-console program + + +After successful build of the project (see \ref compilation2) the concordia-console program is available in the folder build/concordia-console. + +\subsection running2_1 concordia-console options + +The full list of program options is given below: + +\verbatim + -h [ --help ] Display this message + -c [ --config ] arg Concordia configuration file (required) +\endverbatim + +\subsection running2_2 concordia-console example run + +\subsection running2_3 concordia-console output format + + +\section running3 The Concordia configuration + +Concordia is configured by the means of a configuration file in the libconfig format (http://www.hyperrealm.com/libconfig/). diff --git a/concordia-server/t/CMakeLists.txt b/concordia-server/t/CMakeLists.txt new file mode 100644 index 0000000..ddc9c13 --- /dev/null +++ b/concordia-server/t/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(concordia-server-tests + test_concordia.cpp + test_concordia_config.cpp + ) + +target_link_libraries(concordia-server-tests concordia ${LIBCONFIG_LIB} concordia-tests-common) diff --git a/concordia-server/t/test_concordia.cpp b/concordia-server/t/test_concordia.cpp new file mode 100644 index 0000000..9248238 --- /dev/null +++ b/concordia-server/t/test_concordia.cpp @@ -0,0 +1,19 @@ +#include "tests/unit-tests/unit_tests_globals.hpp" +#include "concordia/concordia.hpp" +#include "tests/common/test_resources_manager.hpp" + + +#include + +using namespace std; + +BOOST_AUTO_TEST_SUITE(concordia_main) + +BOOST_AUTO_TEST_CASE( ConcordiaVersion ) +{ + Concordia concordia = Concordia(TestResourcesManager::getTestConcordiaConfigFilePath("concordia.cfg")); + string version = concordia.getVersion(); + BOOST_CHECK_EQUAL( version , "0.1"); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/concordia-server/t/test_concordia_config.cpp b/concordia-server/t/test_concordia_config.cpp new file mode 100644 index 0000000..9e6566b --- /dev/null +++ b/concordia-server/t/test_concordia_config.cpp @@ -0,0 +1,52 @@ +#include "tests/unit-tests/unit_tests_globals.hpp" + +#include "concordia/concordia_config.hpp" +#include "tests/common/test_resources_manager.hpp" + +#include +#include +#include + +using namespace std; + +BOOST_AUTO_TEST_SUITE(concordia_config) + +BOOST_AUTO_TEST_CASE( ConfigParameters ) +{ + ConcordiaConfig config(TestResourcesManager::getTestConcordiaConfigFilePath("concordia-test.cfg")); + BOOST_CHECK_EQUAL( config.getPuddleTagsetFilePath() , "puddle/tagset.txt" ); +} + +BOOST_AUTO_TEST_CASE( NonexistentConfigTest ) +{ + bool exceptionThrown = false; + string message = ""; + try { + ConcordiaConfig config(TestResourcesManager::getTestConcordiaConfigFilePath("foo.cfg")); + } catch (ConcordiaException & e) { + exceptionThrown = true; + message = e.what(); + } + BOOST_CHECK_EQUAL(exceptionThrown, true); + BOOST_CHECK_EQUAL(boost::starts_with(message, "I/O error reading config file"), true); +} + + +BOOST_AUTO_TEST_CASE( InvalidConfigTest ) +{ + bool exceptionThrown = false; + string message = ""; + try { + ConcordiaConfig config(TestResourcesManager::getTestConcordiaConfigFilePath("invalid.cfg")); + } catch (ConcordiaException & e) { + exceptionThrown = true; + message = e.what(); + } + BOOST_CHECK_EQUAL(exceptionThrown, true); + BOOST_CHECK_EQUAL(boost::starts_with(message, "Error parsing config file"), true); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/concordia-server/technical.dox b/concordia-server/technical.dox new file mode 100644 index 0000000..d64b24e --- /dev/null +++ b/concordia-server/technical.dox @@ -0,0 +1,28 @@ +/** \page technical Project technical information + +\section technical1 Development + +\subsection technical1_1 Code style + +Use: ./run-checkers.sh script to find the most +C++ coding errors. The script uses the following +external tools: + +- cpplint.py (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=cpplint) +- cppcheck + +The reports are stored in the XXX-result.txt files (where XXX is the name of the tool) +in the current directory. + +\subsection technical1_2 Unit tests + +Unit tests are integrated into makefiles. Unit tests codes are +put in the t/ subdirectory for each library. + +In order to run all unit tests just type: + +make test + +You can get detailed test report by running: + +./tests/unit-tests/test_runner diff --git a/concordia-server/test.html b/concordia-server/test.html new file mode 100644 index 0000000..c5ba0af --- /dev/null +++ b/concordia-server/test.html @@ -0,0 +1,7 @@ + + + + + + +