X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_multi.cpp;h=33de6a4235563ea70456cf9e143d61ba533136d8;hb=6e5694249f3031e2d1d09ef4449e446403054d5e;hp=b0bf21f9f37b48427f964e38f8cbf52d79f32974;hpb=d0123337d70b0fb97b578cc57467bb94980f1014;p=metaproxy-moved-to-github.git diff --git a/src/filter_multi.cpp b/src/filter_multi.cpp index b0bf21f..33de6a4 100644 --- a/src/filter_multi.cpp +++ b/src/filter_multi.cpp @@ -1,5 +1,5 @@ /* This file is part of Metaproxy. - Copyright (C) 2005-2009 Index Data + Copyright (C) 2005-2011 Index Data Metaproxy 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 @@ -20,20 +20,21 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "config.hpp" -#include "filter.hpp" -#include "package.hpp" +#include +#include #include #include #include #include -#include "util.hpp" +#include #include "filter_multi.hpp" #include #include #include +#include #include #include @@ -104,13 +105,23 @@ namespace metaproxy_1 { void present(Package &package, Z_APDU *apdu); void scan1(Package &package, Z_APDU *apdu); void scan2(Package &package, Z_APDU *apdu); + void relay_apdu(Package &package, Z_APDU *apdu); Rep *m_p; }; - struct Multi::Map { - Map(std::list hosts, std::string route); - Map(); - std::list m_hosts; + class Multi::Map { + std::string m_target_pattern; std::string m_route; + public: + Map(std::string pattern, std::string route) : + m_target_pattern(pattern), m_route(route) {}; + bool match(const std::string target, std::string *ret) const { + if (yaz_match_glob(m_target_pattern.c_str(), target.c_str())) + { + *ret = m_route; + return true; + } + return false; + }; }; class Multi::Rep { friend class Multi; @@ -120,7 +131,7 @@ namespace metaproxy_1 { FrontendPtr get_frontend(Package &package); void release_frontend(Package &package); private: - std::map m_target_route; + std::list m_route_patterns; boost::mutex m_mutex; boost::condition m_cond_session_ready; std::map m_clients; @@ -212,15 +223,6 @@ yf::Multi::FrontendSet::~FrontendSet() { } -yf::Multi::Map::Map(std::list hosts, std::string route) - : m_hosts(hosts), m_route(route) -{ -} - -yf::Multi::Map::Map() -{ -} - yf::Multi::Multi() : m_p(new Multi::Rep) { } @@ -388,7 +390,14 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) Backend *b = new Backend; b->m_vhost = *t_it; - b->m_route = m_p->m_target_route[*t_it]; + std::list::const_iterator it = + m_p->m_route_patterns.begin(); + while (it != m_p->m_route_patterns.end()) { + if (it->match(*t_it, &b->m_route)) + break; + it++; + } + // b->m_route = m_p->m_target_route[*t_it]; // b->m_route unset b->m_package = PackagePtr(new Package(s, package.origin())); @@ -409,16 +418,22 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) mp::util::set_vhost_otherinfo(&init_apdu->u.initRequest->otherInfo, odr, vhost_one); - Z_InitRequest *req = init_apdu->u.initRequest; + + Z_InitRequest *breq = init_apdu->u.initRequest; + + breq->idAuthentication = req->idAuthentication; - ODR_MASK_SET(req->options, Z_Options_search); - ODR_MASK_SET(req->options, Z_Options_present); - ODR_MASK_SET(req->options, Z_Options_namedResultSets); - ODR_MASK_SET(req->options, Z_Options_scan); + *breq->preferredMessageSize = *req->preferredMessageSize; + *breq->maximumRecordSize = *req->maximumRecordSize; + + ODR_MASK_SET(breq->options, Z_Options_search); + ODR_MASK_SET(breq->options, Z_Options_present); + ODR_MASK_SET(breq->options, Z_Options_namedResultSets); + ODR_MASK_SET(breq->options, Z_Options_scan); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3); + ODR_MASK_SET(breq->protocolVersion, Z_ProtocolVersion_1); + ODR_MASK_SET(breq->protocolVersion, Z_ProtocolVersion_2); + ODR_MASK_SET(breq->protocolVersion, Z_ProtocolVersion_3); b->m_package->request() = init_apdu; @@ -435,6 +450,7 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) ODR_MASK_SET(f_resp->options, Z_Options_search); ODR_MASK_SET(f_resp->options, Z_Options_present); ODR_MASK_SET(f_resp->options, Z_Options_namedResultSets); + ODR_MASK_SET(f_resp->options, Z_Options_scan); ODR_MASK_SET(f_resp->protocolVersion, Z_ProtocolVersion_1); ODR_MASK_SET(f_resp->protocolVersion, Z_ProtocolVersion_2); @@ -442,6 +458,9 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) int no_failed = 0; int no_succeeded = 0; + + Odr_int preferredMessageSize = *req->preferredMessageSize; + Odr_int maximumRecordSize = *req->maximumRecordSize; for (bit = m_backend_list.begin(); bit != m_backend_list.end(); ) { PackagePtr p = (*bit)->m_package; @@ -453,8 +472,6 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) bit = m_backend_list.erase(bit); continue; } - no_succeeded++; - Z_GDU *gdu = p->response().get(); if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which == Z_APDU_initResponse) @@ -473,28 +490,39 @@ void yf::Multi::Frontend::init(mp::Package &package, Z_GDU *gdu) for (i = 0; i <= Z_ProtocolVersion_3; i++) if (!ODR_MASK_GET(b_resp->protocolVersion, i)) ODR_MASK_CLEAR(f_resp->protocolVersion, i); - // reject if any of the backends reject - if (!*b_resp->result) - *f_resp->result = 0; + if (*b_resp->result) + { + no_succeeded++; + if (preferredMessageSize > *b_resp->preferredMessageSize) + preferredMessageSize = *b_resp->preferredMessageSize; + if (maximumRecordSize > *b_resp->maximumRecordSize) + maximumRecordSize = *b_resp->maximumRecordSize; + } + else + no_failed++; } else - { - // if any target does not return init return that (close or - // similar ) - package.response() = p->response(); - return; - } + no_failed++; bit++; } + *f_resp->preferredMessageSize = preferredMessageSize; + *f_resp->maximumRecordSize = maximumRecordSize; + if (m_p->m_hide_unavailable) { if (no_succeeded == 0) + { + *f_resp->result = 0; package.session().close(); + } } else { if (no_failed) + { + *f_resp->result = 0; package.session().close(); + } } package.response() = f_apdu; } @@ -505,9 +533,9 @@ void yf::Multi::Frontend::search(mp::Package &package, Z_APDU *apdu_req) Z_SearchRequest *req = apdu_req->u.searchRequest; // save these for later - int smallSetUpperBound = *req->smallSetUpperBound; - int largeSetLowerBound = *req->largeSetLowerBound; - int mediumSetPresentNumber = *req->mediumSetPresentNumber; + Odr_int smallSetUpperBound = *req->smallSetUpperBound; + Odr_int largeSetLowerBound = *req->largeSetLowerBound; + Odr_int mediumSetPresentNumber = *req->mediumSetPresentNumber; // they are altered now - to disable piggyback *req->smallSetUpperBound = 0; @@ -538,7 +566,7 @@ void yf::Multi::Frontend::search(mp::Package &package, Z_APDU *apdu_req) // look at each response FrontendSet resultSet(std::string(req->resultSetName)); - int result_set_size = 0; + Odr_int result_set_size = 0; Z_Records *z_records_diag = 0; // no diagnostics (yet) for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) { @@ -591,12 +619,13 @@ void yf::Multi::Frontend::search(mp::Package &package, Z_APDU *apdu_req) // assume OK m_sets[resultSet.m_setname] = resultSet; - int number; + Odr_int number; mp::util::piggyback(smallSetUpperBound, - largeSetLowerBound, - mediumSetPresentNumber, - result_set_size, - number); + largeSetLowerBound, + mediumSetPresentNumber, + 0, 0, + result_set_size, + number, 0); Package pp(package.session(), package.origin()); if (number > 0) { @@ -758,6 +787,14 @@ void yf::Multi::Frontend::present(mp::Package &package, Z_APDU *apdu_req) f_resp->records = z_records_diag; *f_resp->presentStatus = Z_PresentStatus_failure; } + else if (number < 0 || (size_t) number > jobs.size()) + { + f_apdu = + odr.create_presentResponse( + apdu_req, + YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, + 0); + } else { f_resp->records = (Z_Records *) odr_malloc(odr, sizeof(Z_Records)); @@ -889,6 +926,30 @@ Z_Entry *yf::Multi::ScanTermInfo::get_entry(ODR odr) return e; } +void yf::Multi::Frontend::relay_apdu(mp::Package &package, Z_APDU *apdu_req) +{ + std::list::const_iterator bit; + for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) + { + PackagePtr p = (*bit)->m_package; + mp::odr odr; + + p->request() = apdu_req; + p->copy_filter(package); + } + multi_move(m_backend_list); + for (bit = m_backend_list.begin(); bit != m_backend_list.end(); bit++) + { + PackagePtr p = (*bit)->m_package; + + if (p->session().is_closed()) // if any backend closes, close frontend + package.session().close(); + + package.response() = p->response(); + } +} + + void yf::Multi::Frontend::scan2(mp::Package &package, Z_APDU *apdu_req) { Z_ScanRequest *req = apdu_req->u.scanRequest; @@ -968,7 +1029,7 @@ void yf::Multi::Frontend::scan2(mp::Package &package, Z_APDU *apdu_req) { ScanTermInfo my; - int *occur = ent->u.termInfo->globalOccurrences; + Odr_int *occur = ent->u.termInfo->globalOccurrences; my.m_count = occur ? *occur : 0; if (ent->u.termInfo->term->which == Z_Term_general) @@ -1009,7 +1070,7 @@ void yf::Multi::Frontend::scan2(mp::Package &package, Z_APDU *apdu_req) { ScanTermInfo my; - int *occur = ent->u.termInfo->globalOccurrences; + Odr_int *occur = ent->u.termInfo->globalOccurrences; my.m_count = occur ? *occur : 0; if (ent->u.termInfo->term->which == Z_Term_general) @@ -1156,6 +1217,10 @@ void yf::Multi::process(mp::Package &package) const { f->scan2(package, apdu); } + else if (apdu->which == Z_APDU_close) + { + f->relay_apdu(package, apdu); + } else { mp::odr odr; @@ -1170,7 +1235,8 @@ void yf::Multi::process(mp::Package &package) const m_p->release_frontend(package); } -void mp::filter::Multi::configure(const xmlNode * ptr, bool test_only) +void mp::filter::Multi::configure(const xmlNode * ptr, bool test_only, + const char *path) { for (ptr = ptr->children; ptr; ptr = ptr->next) { @@ -1180,7 +1246,7 @@ void mp::filter::Multi::configure(const xmlNode * ptr, bool test_only) { std::string route = mp::xml::get_route(ptr); std::string target = mp::xml::get_text(ptr); - m_p->m_target_route[target] = route; + m_p->m_route_patterns.push_back(Multi::Map(target, route)); } else if (!strcmp((const char *) ptr->name, "hideunavailable")) {