concordia-server

Former-commit-id: d6738a8d8b0c9482ef5a7416af5b732422e37dbe
This commit is contained in:
Rafał Jaworski 2014-04-10 10:35:23 +02:00
parent 8a38831306
commit 5d56065e93
14 changed files with 455 additions and 0 deletions

View File

@ -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/)

View File

@ -0,0 +1,99 @@
#include <iostream>
#include <sstream>
#include <string>
#include <boost/algorithm/string/replace.hpp>
#include <fcgio.h>
#include <stdlib.h>
#include <unistd.h>
#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;
}

View File

@ -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)

View File

@ -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 <form>)

View File

@ -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<br/>
cd build<br/>
../cmake.sh<br/>
make<br/>
make test<br/>
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.
*/

View File

@ -0,0 +1,62 @@
#include "concordia-server/concordia_server.hpp"
#include <sstream>
#include <concordia/example.hpp>
#include <concordia/substring_occurence.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/foreach.hpp>
ConcordiaServer::ConcordiaServer(const std::string & configFilePath)
throw(ConcordiaException) {
_concordia = boost::shared_ptr<Concordia> (
new Concordia(configFilePath));
}
ConcordiaServer::~ConcordiaServer() {
}
string ConcordiaServer::handleRequest(string & requestString) {
stringstream ss;
try {
ss << "Content-type: text/html\r\n"
<< "\r\n"
<< "<html>\n"
<< " <head>\n"
<< " <title>Hello, World!</title>\n"
<< " </head>\n"
<< " <body>\n"
<< " <h1>Hello, World!</h1>\n"
<< " The concordia version is: "<< _concordia->getVersion() << "\n"
<< " <h1>Input data:</h1>\n"
<< requestString;
ss << " <h1>Adding content as example:</h1>\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 << " <h1>Searching ma kota:</h1>\n";
boost::ptr_vector<SubstringOccurence> result =
_concordia->simpleSearch("ma kota");
BOOST_FOREACH(SubstringOccurence occurence, result) {
ss << "\t\tfound match in sentence number: "
<< occurence.getId() << "<br/><br/>";
}
ss << " </body>\n"
<< "</html>\n";
} catch (ConcordiaException & e) {
ss << "<h1> Concordia error:" << e.what() << "</h1>";
}
return ss.str();
}

View File

@ -0,0 +1,30 @@
#ifndef CONCORDIA_SERVER_HDR
#define CONCORDIA_SERVER_HDR
#include <string>
#include <concordia/concordia_exception.hpp>
#include <boost/shared_ptr.hpp>
#include <concordia/concordia.hpp>
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> _concordia;
};
#endif

12
concordia-server/main.dox Normal file
View File

@ -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.
*/

View File

@ -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/).

View File

@ -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)

View File

@ -0,0 +1,19 @@
#include "tests/unit-tests/unit_tests_globals.hpp"
#include "concordia/concordia.hpp"
#include "tests/common/test_resources_manager.hpp"
#include <string>
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()

View File

@ -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 <string>
#include <list>
#include <boost/algorithm/string/predicate.hpp>
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()

View File

@ -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

View File

@ -0,0 +1,7 @@
<html>
<body>
<form enctype="multipart/form-data" action="http://localhost:8081" accept-charset="UTF-8" method="POST">
<input type="text" name="input_field" />
</form>
</body>
</html>