From: Adam Dickmeiss Date: Thu, 13 Oct 2005 20:06:45 +0000 (+0000) Subject: Implemented FilterFrontendNet which is a network server based on X-Git-Tag: YP2.0.0.2~218 X-Git-Url: http://lists.indexdata.dk/?a=commitdiff_plain;h=57c1c4822f1de4d983c1aee3bc6059ad2600d991;p=metaproxy-moved-to-github.git Implemented FilterFrontendNet which is a network server based on YAZ/YAZ++. --- diff --git a/src/.cvsignore b/src/.cvsignore index 658a82a..6b3317f 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -4,15 +4,17 @@ *.la stamp-h* config.hpp +socket Makefile Makefile.in config.hpp.in +test_boost_threads +test_boost_time test_filter1 test_filter2 +test_filter_frontend_net +test_package1 +test_thread_pool_observer test_session1 test_session2 -test_boost_threads -test_boost_time -design p2 -test_thread_pool_observer diff --git a/src/Makefile.am b/src/Makefile.am index 229a720..1587d49 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,51 +1,64 @@ -## $Id: Makefile.am,v 1.16 2005-10-13 12:28:55 adam Exp $ +## $Id: Makefile.am,v 1.17 2005-10-13 20:06:45 adam Exp $ MAINTAINERCLEANFILES = Makefile.in config.in config.hpp AM_CXXFLAGS = $(YAZPPINC) $(XSLT_CFLAGS) -YP2_INCHPP = session.hpp package.hpp filter.hpp router.hpp +# Rules for the library.. + +lib_LTLIBRARIES = libyp2.la +libyp2_la_LDFLAGS = -version-info 0:0:0 + +libyp2_la_SOURCES = filter_frontend_net.cpp filter_frontend_net.hpp \ + session.cpp session.hpp package.hpp filter.hpp router.hpp \ + thread_pool_observer.cpp thread_pool_observer.hpp + +# Rules for programs.. + +LDADD= libyp2.la $(YAZPPLALIB) $(XSLT_LIBS) bin_PROGRAMS = +noinst_PROGRAMS = p2 + +p2_SOURCES=p2_frontend.cpp p2_msg.cpp p2.cpp p2_frontend.h \ + p2_config.cpp p2_config.h \ + p2_backend.h p2_backend_dummy.cpp \ + p2_modules.cpp p2_modules.h \ + p2_xmlerror.cpp p2_xmlerror.h + +# Rules for test programs.. + check_PROGRAMS = \ test_package1 \ test_filter1 test_filter2 \ test_session1 test_session2 \ test_thread_pool_observer \ - test_boost_threads test_boost_time -noinst_PROGRAMS = p2 + test_boost_threads test_boost_time \ + test_filter_frontend_net TESTS=$(check_PROGRAMS) -test_package1_SOURCES=test_package1.cpp $(YP2_INCHPP) -test_filter1_SOURCES=test_filter1.cpp $(YP2_INCHPP) -test_filter2_SOURCES=test_filter2.cpp $(YP2_INCHPP) -test_session1_SOURCES=test_session1.cpp $(YP2_INCHPP) -test_session2_SOURCES=test_session2.cpp $(YP2_INCHPP) +test_package1_SOURCES=test_package1.cpp +test_filter1_SOURCES=test_filter1.cpp +test_filter2_SOURCES=test_filter2.cpp +test_session1_SOURCES=test_session1.cpp +test_session2_SOURCES=test_session2.cpp test_boost_threads_SOURCES=test_boost_threads.cpp test_boost_time_SOURCES=test_boost_time.cpp -test_thread_pool_observer_SOURCES = test_thread_pool_observer.cpp \ - thread_pool_observer.cpp thread_pool_observer.h - -p2_SOURCES=p2_frontend.cpp p2_msg.cpp p2.cpp p2_frontend.h \ - p2_config.cpp p2_config.h \ - p2_backend.h p2_backend_dummy.cpp \ - p2_modules.cpp p2_modules.h \ - p2_xmlerror.cpp p2_xmlerror.h \ - thread_pool_observer.cpp thread_pool_observer.h - +test_thread_pool_observer_SOURCES = test_thread_pool_observer.cpp +test_filter_frontend_net_SOURCES = test_filter_frontend_net.cpp -LDADD= $(YAZPPLALIB) $(XSLT_LIBS) -TLDADD = $(LDADD) -lboost_unit_test_framework +TESTLDADD = $(LDADD) -lboost_unit_test_framework -test_filter1_LDADD = $(TLDADD) -test_filter2_LDADD = $(TLDADD) -test_session1_LDADD = $(TLDADD) -test_session2_LDADD = $(TLDADD) -test_boost_threads_LDADD = $(TLDADD) -test_boost_time_LDADD = $(TLDADD) -test_thread_pool_observer_LDADD = $(TLDADD) -test_package1_LDADD = $(TLDADD) +test_filter1_LDADD = $(TESTLDADD) +test_filter2_LDADD = $(TESTLDADD) +test_session1_LDADD = $(TESTLDADD) +test_session2_LDADD = $(TESTLDADD) +test_boost_threads_LDADD = $(TESTLDADD) +test_boost_time_LDADD = $(TESTLDADD) +test_thread_pool_observer_LDADD = $(TESTLDADD) +test_package1_LDADD = $(TESTLDADD) +test_filter_frontend_net_LDADD = $(TESTLDADD) # doxygen target dox: diff --git a/src/filter_frontend_net.cpp b/src/filter_frontend_net.cpp new file mode 100644 index 0000000..ed9a475 --- /dev/null +++ b/src/filter_frontend_net.cpp @@ -0,0 +1,270 @@ + + +#include "config.hpp" + +#include "filter.hpp" +#include "router.hpp" +#include "package.hpp" +#include "thread_pool_observer.hpp" +#include "filter_frontend_net.hpp" +#include +#include +#include +#include + +#include + +using namespace yp2; + +class P2_Session : public yazpp_1::Z_Assoc { +public: + ~P2_Session(); + P2_Session(yazpp_1::IPDU_Observable *the_PDU_Observable, + ThreadPoolSocketObserver *m_my_thread, + const Package *package); + int m_no_requests; +private: + yazpp_1::IPDU_Observer* sessionNotify( + yazpp_1::IPDU_Observable *the_PDU_Observable, + int fd); + void recv_GDU(Z_GDU *apdu, int len); + + void failNotify(); + void timeoutNotify(); + void connectNotify(); +private: + ThreadPoolSocketObserver *m_my_thread; + Session m_session; + Origin m_origin; + bool m_delete_flag; + const Package *m_package; +}; + + +class ThreadPoolPackage : public IThreadPoolMsg { +public: + ThreadPoolPackage(Package *package, P2_Session *ses) : + m_session(ses), m_package(package) { }; + ~ThreadPoolPackage(); + IThreadPoolMsg *handle(); + void result(); + +private: + P2_Session *m_session; + Package *m_package; + +}; + +ThreadPoolPackage::~ThreadPoolPackage() +{ + delete m_package; +} + +void ThreadPoolPackage::result() +{ + m_session->m_no_requests--; + + yazpp_1::GDU *gdu = &m_package->response(); + if (gdu->get()) + { + int len; + m_session->send_GDU(gdu->get(), &len); + } +} + +IThreadPoolMsg *ThreadPoolPackage::handle() +{ + m_package->move(); + return this; +} + + +P2_Session::P2_Session(yazpp_1::IPDU_Observable *the_PDU_Observable, + ThreadPoolSocketObserver *my_thread_pool, + const Package *package) + : Z_Assoc(the_PDU_Observable) +{ + m_my_thread = my_thread_pool; + m_no_requests = 0; + m_delete_flag = false; + m_package = package; +} + + +yazpp_1::IPDU_Observer *P2_Session::sessionNotify(yazpp_1::IPDU_Observable + *the_PDU_Observable, int fd) +{ + return 0; +} + +P2_Session::~P2_Session() +{ +} + +void P2_Session::recv_GDU(Z_GDU *z_pdu, int len) +{ + m_no_requests++; + + Package *p = new Package(m_session, m_origin); + + ThreadPoolPackage *m = new ThreadPoolPackage(p, this); + p->copy_filter(*m_package); + p->request() = yazpp_1::GDU(z_pdu); + m_my_thread->put(m); +} + +void P2_Session::failNotify() +{ + // TODO: send Package to signal "close" + m_delete_flag = true; + if (m_no_requests == 0) + delete this; + +} + +void P2_Session::timeoutNotify() +{ + // TODO: send Package to signal "close" + m_delete_flag = true; + if (m_no_requests == 0) + delete this; +} + +void P2_Session::connectNotify() +{ + +} + +class P2_Server : public yazpp_1::Z_Assoc { +public: + ~P2_Server(); + P2_Server(yazpp_1::IPDU_Observable *the_PDU_Observable, + ThreadPoolSocketObserver *m_my_thread, + const Package *package); +private: + yazpp_1::IPDU_Observer* sessionNotify( + yazpp_1::IPDU_Observable *the_PDU_Observable, + int fd); + void recv_GDU(Z_GDU *apdu, int len); + + void failNotify(); + void timeoutNotify(); + void connectNotify(); +private: + ThreadPoolSocketObserver *m_my_thread; + const Package *m_package; +}; + + +P2_Server::P2_Server(yazpp_1::IPDU_Observable *the_PDU_Observable, + ThreadPoolSocketObserver *my_thread, + const Package *package) + : Z_Assoc(the_PDU_Observable) +{ + m_my_thread = my_thread; + m_package = package; + +} + +yazpp_1::IPDU_Observer *P2_Server::sessionNotify(yazpp_1::IPDU_Observable + *the_PDU_Observable, int fd) +{ + P2_Session *my = new P2_Session(the_PDU_Observable, m_my_thread, + m_package); + return my; +} + +P2_Server::~P2_Server() +{ +} + +void P2_Server::recv_GDU(Z_GDU *apdu, int len) +{ +} + +void P2_Server::failNotify() +{ +} + +void P2_Server::timeoutNotify() +{ +} + +void P2_Server::connectNotify() +{ +} + +FilterFrontendNet::FilterFrontendNet() +{ + m_no_threads = 5; + m_listen_address = "@:9001"; + m_listen_duration = 0; +} + +class My_Timer_Thread : public yazpp_1::ISocketObserver { +private: + yazpp_1::ISocketObservable *m_obs; + int m_fd[2]; + bool m_timeout; +public: + My_Timer_Thread(yazpp_1::ISocketObservable *obs, int duration); + void socketNotify(int event); + bool timeout(); +}; + +bool My_Timer_Thread::timeout() +{ + return m_timeout; +} + +My_Timer_Thread::My_Timer_Thread(yazpp_1::ISocketObservable *obs, + int duration) : + m_obs(obs), m_timeout(false) +{ + pipe(m_fd); + obs->addObserver(m_fd[0], this); + obs->maskObserver(this, yazpp_1::SOCKET_OBSERVE_READ); + obs->timeoutObserver(this, duration); +} + +void My_Timer_Thread::socketNotify(int event) +{ + m_timeout = true; + m_obs->deleteObserver(this); + close(m_fd[0]); + close(m_fd[1]); +} + +Package &FilterFrontendNet::process(Package &package) const { + yazpp_1::SocketManager mySocketManager; + + My_Timer_Thread *tt = 0; + if (m_listen_duration) + tt = new My_Timer_Thread(&mySocketManager, m_listen_duration); + + yazpp_1::PDU_Assoc *my_PDU_Assoc = + new yazpp_1::PDU_Assoc(&mySocketManager); + + ThreadPoolSocketObserver threadPool(&mySocketManager, m_no_threads); + + P2_Server z(my_PDU_Assoc, &threadPool, &package); + z.server(m_listen_address.c_str()); + + while (mySocketManager.processEvent() > 0) + { + if (tt && tt->timeout()) + break; + } + return package; +} + +std::string &FilterFrontendNet::listen_address() +{ + return m_listen_address; +} + +int &FilterFrontendNet::listen_duration() +{ + return m_listen_duration; +} + diff --git a/src/filter_frontend_net.hpp b/src/filter_frontend_net.hpp new file mode 100644 index 0000000..b30fabe --- /dev/null +++ b/src/filter_frontend_net.hpp @@ -0,0 +1,33 @@ + +#ifndef FILTER_FRONTEND_NET_HPP +#define FILTER_FRONEND_NET_HPP + +#include + +#include "filter.hpp" + +namespace yp2 { + class FilterFrontendNet : public yp2::Filter { + public: + FilterFrontendNet::FilterFrontendNet(); + yp2::Package & process(yp2::Package & package) const; + private: + int m_no_threads; + std::string m_listen_address; + int m_listen_duration; + public: + /// set function - left val in assignment + std::string & listen_address(); + int &listen_duration(); + }; +} + + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/src/p2_frontend.h b/src/p2_frontend.h index 0476ef2..ea68a14 100644 --- a/src/p2_frontend.h +++ b/src/p2_frontend.h @@ -1,4 +1,4 @@ -/* $Id: p2_frontend.h,v 1.3 2005-10-13 10:00:02 adam Exp $ +/* $Id: p2_frontend.h,v 1.4 2005-10-13 20:06:45 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -26,7 +26,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#include "thread_pool_observer.h" +#include "thread_pool_observer.hpp" #include #include #include diff --git a/src/package.hpp b/src/package.hpp index 719aaf5..d49301c 100644 --- a/src/package.hpp +++ b/src/package.hpp @@ -2,6 +2,7 @@ #ifndef PACKAGE_HPP #define PACKAGE_HPP +#include #include #include @@ -29,7 +30,13 @@ namespace yp2 { Package(yp2::Session &session, yp2::Origin &origin) : m_session(session), m_origin(origin), m_filter(0), m_router(0), m_data(0) {} - + + Package & copy_filter(const Package &p) { + m_router = p.m_router; + m_filter = p.m_filter; + return *this; + } + /// send Package to it's next Filter defined in Router Package & move() { m_filter = m_router->move(m_filter, this); @@ -82,6 +89,14 @@ namespace yp2 { m_router = &router; return *this; } + + yazpp_1::GDU &request() { + return m_request_gdu; + } + + yazpp_1::GDU &response() { + return m_response_gdu; + } private: Session m_session; diff --git a/src/session.cpp b/src/session.cpp new file mode 100644 index 0000000..0977505 --- /dev/null +++ b/src/session.cpp @@ -0,0 +1,19 @@ + +#include + +#include "session.hpp" +#include + +#include "config.hpp" + +// defining and initializing static members +boost::mutex yp2::Session::m_mutex; +unsigned long int yp2::Session::m_global_id = 0; + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/src/session.hpp b/src/session.hpp index 9667a17..52c2d3e 100644 --- a/src/session.hpp +++ b/src/session.hpp @@ -61,11 +61,6 @@ namespace yp2 { } -// defining and initializing static members -boost::mutex yp2::Session::m_mutex; -unsigned long int yp2::Session::m_global_id = 0; - - #endif /* * Local variables: diff --git a/src/test_filter_frontend_net.cpp b/src/test_filter_frontend_net.cpp new file mode 100644 index 0000000..f5ea15a --- /dev/null +++ b/src/test_filter_frontend_net.cpp @@ -0,0 +1,108 @@ + +#include "config.hpp" +#include +#include + +#include "router.hpp" +#include "session.hpp" +#include "package.hpp" +#include "filter_frontend_net.hpp" + +#define BOOST_AUTO_TEST_MAIN +#include + +using namespace boost::unit_test; + +class FilterInit: public yp2::Filter { +public: + yp2::Package & process(yp2::Package & package) const { + ODR odr = odr_createmem(ODR_ENCODE); + Z_APDU *apdu = zget_APDU(odr, Z_APDU_initResponse); + + apdu->u.initResponse->implementationName = "YP2/YAZ"; + + package.response() = apdu; + odr_destroy(odr); + return package.move(); + }; +}; + + +BOOST_AUTO_TEST_CASE( test_filter_frontend_net_1 ) +{ + try + { + { + yp2::FilterFrontendNet nf; + } + BOOST_CHECK(true); + } + catch ( ... ) { + BOOST_CHECK (false); + } +} + +BOOST_AUTO_TEST_CASE( test_filter_frontend_net_2 ) +{ + try + { + { + yp2::RouterChain router; + + FilterInit tf; + + router.rule(tf); + + yp2::Session session; + yp2::Origin origin; + yp2::Package pack_in(session, origin); + + pack_in.router(router).move(); + + yazpp_1::GDU *gdu = &pack_in.response(); + + BOOST_CHECK_EQUAL(gdu->get()->which, Z_GDU_Z3950); + BOOST_CHECK_EQUAL(gdu->get()->u.z3950->which, Z_APDU_initResponse); + } + BOOST_CHECK(true); + } + catch ( ... ) { + BOOST_CHECK (false); + } +} + +BOOST_AUTO_TEST_CASE( test_filter_frontend_net_3 ) +{ + try + { + { + yp2::RouterChain router; + + yp2::FilterFrontendNet filter_front; + filter_front.listen_address() = "unix:socket"; + filter_front.listen_duration() = 2; // listen a short time only + router.rule(filter_front); + + FilterInit filter_init; + router.rule(filter_init); + + yp2::Session session; + yp2::Origin origin; + yp2::Package pack_in(session, origin); + + pack_in.router(router).move(); + } + BOOST_CHECK(true); + } + catch ( ... ) { + BOOST_CHECK (false); + } +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/src/test_thread_pool_observer.cpp b/src/test_thread_pool_observer.cpp index 8086d2c..532aefd 100644 --- a/src/test_thread_pool_observer.cpp +++ b/src/test_thread_pool_observer.cpp @@ -1,4 +1,4 @@ -/* $Id: test_thread_pool_observer.cpp,v 1.3 2005-10-12 23:30:43 adam Exp $ +/* $Id: test_thread_pool_observer.cpp,v 1.4 2005-10-13 20:06:45 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -26,7 +26,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include -#include "thread_pool_observer.h" +#include "thread_pool_observer.hpp" #define BOOST_AUTO_TEST_MAIN #include diff --git a/src/thread_pool_observer.cpp b/src/thread_pool_observer.cpp index b66be7e..de0cf63 100644 --- a/src/thread_pool_observer.cpp +++ b/src/thread_pool_observer.cpp @@ -1,4 +1,4 @@ -/* $Id: thread_pool_observer.cpp,v 1.3 2005-10-12 23:30:43 adam Exp $ +/* $Id: thread_pool_observer.cpp,v 1.4 2005-10-13 20:06:45 adam Exp $ Copyright (c) 1998-2005, Index Data. This file is part of the yaz-proxy. @@ -26,7 +26,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include "config.hpp" -#include "thread_pool_observer.h" +#include "thread_pool_observer.hpp" using namespace yazpp_1; diff --git a/src/thread_pool_observer.h b/src/thread_pool_observer.h deleted file mode 100644 index 34e23a0..0000000 --- a/src/thread_pool_observer.h +++ /dev/null @@ -1,74 +0,0 @@ -/* $Id: thread_pool_observer.h,v 1.2 2005-10-12 23:30:43 adam Exp $ - Copyright (c) 1998-2005, Index Data. - -This file is part of the yaz-proxy. - -YAZ proxy 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, or (at your option) any later -version. - -YAZ proxy 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 YAZ proxy; see the file LICENSE. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - */ - -#include -#include -#include - -#include -#include - -#if HAVE_DLFCN_H -#include -#endif - -#include -#include -#include - -class IThreadPoolMsg { -public: - virtual IThreadPoolMsg *handle() = 0; - virtual void result() = 0; - virtual ~IThreadPoolMsg(); -}; - -class ThreadPoolSocketObserver : public yazpp_1::ISocketObserver { - public: - ThreadPoolSocketObserver(yazpp_1::ISocketObservable *obs, int no_threads); - virtual ~ThreadPoolSocketObserver(); - void socketNotify(int event); - void put(IThreadPoolMsg *m); - IThreadPoolMsg *get(); - void run(void *p); - int m_fd[2]; -private: - yazpp_1::ISocketObservable *m_SocketObservable; - int m_no_threads; - boost::thread_group m_thrds; - - std::deque m_input; - std::deque m_output; - - boost::mutex m_mutex_input_data; - boost::condition m_cond_input_data; - boost::mutex m_mutex_output_data; - bool m_stop_flag; -}; - -/* - * Local variables: - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - * vim: shiftwidth=4 tabstop=8 expandtab - */ - diff --git a/src/thread_pool_observer.hpp b/src/thread_pool_observer.hpp new file mode 100644 index 0000000..0ff7a50 --- /dev/null +++ b/src/thread_pool_observer.hpp @@ -0,0 +1,74 @@ +/* $Id: thread_pool_observer.hpp,v 1.1 2005-10-13 20:06:45 adam Exp $ + Copyright (c) 1998-2005, Index Data. + +This file is part of the yaz-proxy. + +YAZ proxy 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, or (at your option) any later +version. + +YAZ proxy 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 YAZ proxy; see the file LICENSE. If not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. + */ + +#ifndef YP2_THREAD_POOL_OBSERVER_HPP +#define YP2_THREAD_POOL_OBSERVER_HPP + +#include +#include +#include + +#include +#include + +#include +#include +#include + +class IThreadPoolMsg { +public: + virtual IThreadPoolMsg *handle() = 0; + virtual void result() = 0; + virtual ~IThreadPoolMsg(); +}; + +class ThreadPoolSocketObserver : public yazpp_1::ISocketObserver { + public: + ThreadPoolSocketObserver(yazpp_1::ISocketObservable *obs, int no_threads); + virtual ~ThreadPoolSocketObserver(); + void socketNotify(int event); + void put(IThreadPoolMsg *m); + IThreadPoolMsg *get(); + void run(void *p); + int m_fd[2]; +private: + yazpp_1::ISocketObservable *m_SocketObservable; + int m_no_threads; + boost::thread_group m_thrds; + + std::deque m_input; + std::deque m_output; + + boost::mutex m_mutex_input_data; + boost::condition m_cond_input_data; + boost::mutex m_mutex_output_data; + bool m_stop_flag; +}; + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +