From: Adam Dickmeiss Date: Mon, 24 Oct 2005 21:01:53 +0000 (+0000) Subject: More work on Virt_db filter X-Git-Tag: YP2.0.0.2~188 X-Git-Url: http://git.indexdata.com/?a=commitdiff_plain;h=6f81e2e8664bbc26dd3626bb02980cdb7fe0abca;hp=d732b2b2ea19a0669f9a42ca6fd7bc14a3845fc5;p=metaproxy-moved-to-github.git More work on Virt_db filter --- diff --git a/src/filter_virt_db.cpp b/src/filter_virt_db.cpp index e70a791..2a86b79 100644 --- a/src/filter_virt_db.cpp +++ b/src/filter_virt_db.cpp @@ -1,4 +1,4 @@ -/* $Id: filter_virt_db.cpp,v 1.1 2005-10-24 14:33:30 adam Exp $ +/* $Id: filter_virt_db.cpp,v 1.2 2005-10-24 21:01:53 adam Exp $ Copyright (c) 2005, Index Data. %LICENSE% @@ -20,37 +20,63 @@ #include #include +#include #include namespace yf = yp2::filter; namespace yp2 { namespace filter { + struct Virt_db_set { + Virt_db_set(yp2::Session &id, Z_InternationalString *setname, + std::string vhost); + ~Virt_db_set(); + + yp2::Session m_session; + std::string m_setname; + std::string m_vhost; + }; struct Virt_db_session { Virt_db_session(yp2::Session &id, bool use_vhost); yp2::Session m_session; bool m_use_vhost; + std::list m_sets; }; struct Virt_db_map { - Virt_db_map(std::string database, std::string vhost); - std::string m_database; + Virt_db_map(std::string vhost); + Virt_db_map(); std::string m_vhost; }; class Virt_db::Rep { friend class Virt_db; void release_session(Package &package); - void init(Package &package, Z_APDU *apdu); - void search(Package &package, Z_APDU *apdu); + void init(Package &package, Z_APDU *apdu, bool &move_later); + void search(Package &package, Z_APDU *apdu, bool &move_later); private: + boost::mutex m_sessions_mutex; std::listm_sessions; - std::listm_maps; + std::mapm_maps; }; } } -yf::Virt_db_map::Virt_db_map(std::string database, std::string vhost) - : m_database(database), m_vhost(vhost) +yf::Virt_db_set::Virt_db_set(yp2::Session &id, Z_InternationalString *setname, + std::string vhost) + : m_session(id), m_setname(setname), m_vhost(vhost) +{ +} + +yf::Virt_db_set::~Virt_db_set() +{ +} + +yf::Virt_db_map::Virt_db_map(std::string vhost) + : m_vhost(vhost) +{ +} + +yf::Virt_db_map::Virt_db_map() { } @@ -71,27 +97,50 @@ yf::Virt_db::~Virt_db() { void yf::Virt_db::Rep::release_session(Package &package) { - + if (package.session().is_closed()) + { + boost::mutex::scoped_lock lock(m_sessions_mutex); + + std::list::iterator it; + for (it = m_sessions.begin(); it != m_sessions.end(); it++) + { + if (package.session() == (*it).m_session) + break; + } + if (it == m_sessions.end()) + return; + m_sessions.erase(it); + } } -void yf::Virt_db::Rep::search(Package &package, Z_APDU *apdu) +void yf::Virt_db::Rep::search(Package &package, Z_APDU *apdu, bool &move_later) { Z_SearchRequest *req = apdu->u.searchRequest; - - std::list::iterator it; - for (it = m_sessions.begin(); it != m_sessions.end(); it++) - { - if (package.session() == (*it).m_session) - break; - } - if (it == m_sessions.end()) - return; - if ((*it).m_use_vhost) - package.move(); - else + std::string vhost; + std::string database; + Session *id = 0; { - if (req->num_databaseNames != 1) + boost::mutex::scoped_lock lock(m_sessions_mutex); + + std::list::iterator it; + for (it = m_sessions.begin(); it != m_sessions.end(); it++) { + if (package.session() == (*it).m_session) + break; + } + if (it == m_sessions.end()) + { + // error should be returned + move_later = true; + return; + } + if ((*it).m_use_vhost) + { + move_later = true; + return; + } + if (req->num_databaseNames != 1) + { // exactly one database must be specified ODR odr = odr_createmem(ODR_ENCODE); Z_APDU *apdu = zget_APDU(odr, Z_APDU_searchResponse); @@ -104,13 +153,85 @@ void yf::Virt_db::Rep::search(Package &package, Z_APDU *apdu) package.response() = apdu; odr_destroy(odr); + return; } - const char *database = req->databaseNames[0]; + database = req->databaseNames[0]; + std::map::iterator map_it; + map_it = m_maps.find(database); + if (map_it == m_maps.end()) + { // no map for database: return diagnostic + ODR odr = odr_createmem(ODR_ENCODE); + Z_APDU *apdu = zget_APDU(odr, Z_APDU_searchResponse); + + Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records)); + apdu->u.searchResponse->records = rec; + rec->which = Z_Records_NSD; + rec->u.nonSurrogateDiagnostic = + zget_DefaultDiagFormat( + odr, YAZ_BIB1_DATABASE_UNAVAILABLE, database.c_str()); + package.response() = apdu; + + odr_destroy(odr); + return; + } + vhost = map_it->second.m_vhost; + id = new Session; + (*it).m_sets.push_back(Virt_db_set(*id, req->resultSetName, vhost)); } + const char *vhost_cstr = vhost.c_str(); + if (true) + { // sending init to backend + Package init_package(*id, package.origin()); + init_package.copy_filter(package); + + ODR odr = odr_createmem(ODR_ENCODE); + Z_APDU *init_apdu = zget_APDU(odr, Z_APDU_initRequest); + + yaz_oi_set_string_oidval(&init_apdu->u.initRequest->otherInfo, odr, + VAL_PROXY, 1, vhost_cstr); + + init_package.request() = init_apdu; + odr_destroy(odr); + + init_package.move(); // send init + + if (init_package.session().is_closed()) + { + ODR odr = odr_createmem(ODR_ENCODE); + Z_APDU *apdu = zget_APDU(odr, Z_APDU_searchResponse); + + Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records)); + apdu->u.searchResponse->records = rec; + rec->which = Z_Records_NSD; + rec->u.nonSurrogateDiagnostic = + zget_DefaultDiagFormat( + odr, YAZ_BIB1_DATABASE_UNAVAILABLE, database.c_str()); + package.response() = apdu; + + odr_destroy(odr); + return; + } + } + // sending search to backend + Package search_package(*id, package.origin()); + search_package.copy_filter(package); + const char *sep = strchr(vhost_cstr, '/'); + ODR odr = odr_createmem(ODR_ENCODE); + if (sep) + req->databaseNames[0] = odr_strdup(odr, sep+1); + + search_package.request() = yazpp_1::GDU(apdu); + + odr_destroy(odr); + + search_package.move(); + + package.response() = search_package.response(); } -void yf::Virt_db::Rep::init(Package &package, Z_APDU *apdu) +void yf::Virt_db::Rep::init(Package &package, Z_APDU *apdu, bool &move_later) { + boost::mutex::scoped_lock lock(m_sessions_mutex); std::list::iterator it; for (it = m_sessions.begin(); it != m_sessions.end(); it++) @@ -149,13 +270,13 @@ void yf::Virt_db::Rep::init(Package &package, Z_APDU *apdu) else { m_sessions.push_back(Virt_db_session(package.session(), true)); - package.move(); + move_later = true; } } void yf::Virt_db::add_map_db2vhost(std::string db, std::string vhost) { - m_p->m_maps.push_back(Virt_db_map(db, vhost)); + m_p->m_maps[db] = Virt_db_map(vhost); } void yf::Virt_db::process(Package &package) const @@ -166,14 +287,15 @@ void yf::Virt_db::process(Package &package) const package.move(); else { + bool move_later = false; Z_APDU *apdu = gdu->u.z3950; if (apdu->which == Z_APDU_initRequest) { - m_p->init(package, apdu); + m_p->init(package, apdu, move_later); } else if (apdu->which == Z_APDU_searchRequest) { - m_p->search(package, apdu); + m_p->search(package, apdu, move_later); } else { @@ -187,6 +309,8 @@ void yf::Virt_db::process(Package &package) const package.session().close(); odr_destroy(odr); } + if (move_later) + package.move(); } m_p->release_session(package); }