X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_sru_to_z3950.cpp;h=a0a7d82688c906bded35d2386daccf799de095f0;hb=b70b9ec78f0ab1c3ed3b432de986159129a0e4ed;hp=68dbab33524d5d77d0bf27199a78a41183327736;hpb=098f68aa472b0827a0dfdfda38a338cde577ef98;p=metaproxy-moved-to-github.git diff --git a/src/filter_sru_to_z3950.cpp b/src/filter_sru_to_z3950.cpp index 68dbab3..a0a7d82 100644 --- a/src/filter_sru_to_z3950.cpp +++ b/src/filter_sru_to_z3950.cpp @@ -1,8 +1,8 @@ -/* $Id: filter_sru_to_z3950.cpp,v 1.24 2006-12-28 13:26:06 marc Exp $ - Copyright (c) 2005-2006, Index Data. +/* $Id: filter_sru_to_z3950.cpp,v 1.29 2007-01-25 14:05:54 adam Exp $ + Copyright (c) 2005-2007, Index Data. See the LICENSE file for details - */ +*/ #include "config.hpp" #include "filter.hpp" @@ -23,6 +23,7 @@ #include #include #include +#include namespace mp = metaproxy_1; namespace mp_util = metaproxy_1::util; @@ -34,10 +35,11 @@ namespace metaproxy_1 { class SRUtoZ3950::Impl { public: void configure(const xmlNode *xmlnode); - void process(metaproxy_1::Package &package) const; + void process(metaproxy_1::Package &package); private: union SRW_query {char * cql; char * xcql; char * pqf;}; typedef const int& SRW_query_type; + std::map m_database_explain; private: bool z3950_build_query(mp::odr &odr_en, Z_Query *z_query, @@ -45,8 +47,10 @@ namespace metaproxy_1 { SRW_query_type query_type) const; bool z3950_init_request(mp::Package &package, - const std::string - &database = "Default") const; + mp::odr &odr_en, + Z_SRW_PDU *sru_pdu_res, + const std::string + &database = "Default") const; bool z3950_close_request(mp::Package &package) const; @@ -68,6 +72,9 @@ namespace metaproxy_1 { Z_SRW_scanRequest const *sr_req) const; + bool z3950_to_srw_diagnostics_ok(mp::odr &odr_en, + Z_SRW_searchRetrieveResponse *srw_res, + Z_Records *records) const; int z3950_to_srw_diag(mp::odr &odr_en, Z_SRW_searchRetrieveResponse *srw_res, @@ -94,11 +101,38 @@ void yf::SRUtoZ3950::process(mp::Package &package) const m_p->process(package); } -void yf::SRUtoZ3950::Impl::configure(const xmlNode *xmlnode) +void yf::SRUtoZ3950::Impl::configure(const xmlNode *confignode) { + const xmlNode * dbnode; + + for (dbnode = confignode->children; dbnode; dbnode = dbnode->next){ + if (dbnode->type != XML_ELEMENT_NODE) + continue; + + std::string database; + mp::xml::check_element_mp(dbnode, "database"); + + for (struct _xmlAttr *attr = dbnode->properties; + attr; attr = attr->next){ + + mp::xml::check_attribute(attr, "", "name"); + database = mp::xml::get_text(attr); + + const xmlNode *explainnode; + for (explainnode = dbnode->children; + explainnode; explainnode = explainnode->next){ + if (explainnode->type != XML_ELEMENT_NODE) + continue; + if (explainnode) + break; + } + // assigning explain node to database name - no check yet + m_database_explain.insert(std::make_pair(database, explainnode)); + } + } } -void yf::SRUtoZ3950::Impl::process(mp::Package &package) const +void yf::SRUtoZ3950::Impl::process(mp::Package &package) { Z_GDU *zgdu_req = package.request().get(); @@ -110,47 +144,60 @@ void yf::SRUtoZ3950::Impl::process(mp::Package &package) const // only working on HTTP_Request packages now - - // TODO: Z3950 response parsing and translation to SRU package bool ok = true; mp::odr odr_de(ODR_DECODE); Z_SRW_PDU *sru_pdu_req = 0; mp::odr odr_en(ODR_ENCODE); - //Z_SRW_PDU *sru_pdu_res = 0; Z_SRW_PDU *sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response); + // determine database with the HTTP header information only + mp_util::SRUServerInfo sruinfo = mp_util::get_sru_server_info(package); + std::map::iterator idbexp; + idbexp = m_database_explain.find(sruinfo.database); + + // assign explain config XML DOM node if database is known + const xmlNode *explainnode = 0; + if (idbexp != m_database_explain.end()){ + explainnode = idbexp->second; + } + // just moving package if database is not known + else { + package.move(); + return; + } + + + // decode SRU request Z_SOAP *soap = 0; char *charset = 0; char *stylesheet = 0; + // filter acts as sink for non-valid SRU requests if (! (sru_pdu_req = mp_util::decode_sru_request(package, odr_de, odr_en, sru_pdu_res, soap, charset, stylesheet))) { - mp_util::build_simple_explain(package, odr_en, sru_pdu_res, 0); + mp_util::build_sru_explain(package, odr_en, sru_pdu_res, + sruinfo, explainnode); mp_util::build_sru_response(package, odr_en, soap, sru_pdu_res, charset, stylesheet); package.session().close(); return; } - - // SRU request package translation to Z3950 package - //if (sru_pdu_req) - // std::cout << *sru_pdu_req << "\n"; - //else - // std::cout << "SRU empty\n"; - - - // explain + // filter acts as sink for SRU explain requests if (sru_pdu_req && sru_pdu_req->which == Z_SRW_explain_request) { Z_SRW_explainRequest *er_req = sru_pdu_req->u.explain_request; - //sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response); - - mp_util::build_simple_explain(package, odr_en, sru_pdu_res, er_req); + //mp_util::build_simple_explain(package, odr_en, sru_pdu_res, + // sruinfo, er_req); + mp_util::build_sru_explain(package, odr_en, sru_pdu_res, + sruinfo, explainnode, er_req); + mp_util::build_sru_response(package, odr_en, soap, + sru_pdu_res, charset, stylesheet); + return; } // searchRetrieve @@ -166,7 +213,7 @@ void yf::SRUtoZ3950::Impl::process(mp::Package &package) const ok = mp_util::check_sru_query_exists(package, odr_en, sru_pdu_res, sr_req); - if (ok && z3950_init_request(package)) + if (ok && z3950_init_request(package, odr_en, sru_pdu_res)) { { ok = z3950_search_request(package, odr_en, @@ -202,7 +249,7 @@ void yf::SRUtoZ3950::Impl::process(mp::Package &package) const 4, "scan"); // to be used when we do scan - if (false && z3950_init_request(package)) + if (false && z3950_init_request(package, odr_en, sru_pdu_res)) { z3950_scan_request(package, odr_en, sru_pdu_res, sr_req); z3950_close_request(package); @@ -218,7 +265,7 @@ void yf::SRUtoZ3950::Impl::process(mp::Package &package) const return; } - //mp_util::build_sru_debug_package(package); + // build and send SRU response mp_util::build_sru_response(package, odr_en, soap, sru_pdu_res, charset, stylesheet); return; @@ -228,16 +275,15 @@ void yf::SRUtoZ3950::Impl::process(mp::Package &package) const bool yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package, - const std::string &database) const + mp::odr &odr_en, + Z_SRW_PDU *sru_pdu_res, + const std::string &database) const { // prepare Z3950 package - //Session s; - //Package z3950_package(s, package.origin()); Package z3950_package(package.session(), package.origin()); z3950_package.copy_filter(package); // set initRequest APDU - mp::odr odr_en(ODR_ENCODE); Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_initRequest); Z_InitRequest *init_req = apdu->u.initRequest; //TODO: add user name in apdu @@ -259,11 +305,14 @@ yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package, z3950_package.request() = apdu; // send Z3950 package - // std::cout << "z3950_init_request " << *apdu <<"\n"; z3950_package.move(); // dead Z3950 backend detection if (z3950_package.session().is_closed()){ + yaz_add_srw_diagnostic(odr_en, + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + 2, 0); package.session().close(); return false; } @@ -272,9 +321,15 @@ yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package, Z_GDU *z3950_gdu = z3950_package.response().get(); if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950 - && z3950_gdu->u.z3950->which == Z_APDU_initResponse) + && z3950_gdu->u.z3950->which == Z_APDU_initResponse + && *z3950_gdu->u.z3950->u.initResponse->result) return true; + yaz_add_srw_diagnostic(odr_en, + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + 2, 0); + package.session().close(); return false; } @@ -354,44 +409,52 @@ yf::SRUtoZ3950::Impl::z3950_search_request(mp::Package &package, } z3950_package.request() = apdu; - //std::cout << "z3950_search_request " << *apdu << "\n"; + // send Z39.50 package off to backend z3950_package.move(); Z_GDU *z3950_gdu = z3950_package.response().get(); - //std::cout << "z3950_search_request " << *z3950_gdu << "\n"; //TODO: check success condition - //int yaz_diag_bib1_to_srw (int bib1_code); //int yaz_diag_srw_to_bib1(int srw_code); //Se kode i src/seshigh.c (srw_bend_search, srw_bend_init). - if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950 - && z3950_gdu->u.z3950->which == Z_APDU_searchResponse - && z3950_gdu->u.z3950->u.searchResponse->searchStatus) + if (!z3950_gdu || z3950_gdu->which != Z_GDU_Z3950 + || z3950_gdu->u.z3950->which != Z_APDU_searchResponse + || !z3950_gdu->u.z3950->u.searchResponse + || !z3950_gdu->u.z3950->u.searchResponse->searchStatus) { + yaz_add_srw_diagnostic(odr_en, + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + 2, 0); + package.session().close(); + return false; + } + + // everything fine, continuing + Z_SearchResponse *sr = z3950_gdu->u.z3950->u.searchResponse; - Z_SearchResponse *sr = z3950_gdu->u.z3950->u.searchResponse; - if (sr) - { - // srw'fy number of records - sru_pdu_res->u.response->numberOfRecords - = (int *) odr_malloc(odr_en, sizeof(int *)); - *(sru_pdu_res->u.response->numberOfRecords) = *(sr->resultCount); - - // srw'fy nextRecordPosition - //sru_pdu_res->u.response->nextRecordPosition - // = (int *) odr_malloc(odr_en, sizeof(int *)); - //*(sru_pdu_res->u.response->nextRecordPosition) = 1; - - } - - return true; + // checking non surrogate diagnostics in Z3950 search response package + if (!z3950_to_srw_diagnostics_ok(odr_en, sru_pdu_res->u.response, + sr->records)) + { + return false; } + + // Finally, roll on and srw'fy number of records + sru_pdu_res->u.response->numberOfRecords + = (int *) odr_malloc(odr_en, sizeof(int *)); + *(sru_pdu_res->u.response->numberOfRecords) = *(sr->resultCount); - return false; + // srw'fy nextRecordPosition + //sru_pdu_res->u.response->nextRecordPosition + // = (int *) odr_malloc(odr_en, sizeof(int *)); + //*(sru_pdu_res->u.response->nextRecordPosition) = 1; + + return true; } bool @@ -529,7 +592,7 @@ yf::SRUtoZ3950::Impl::z3950_present_request(mp::Package &package, // attaching Z3950 package to filter chain z3950_package.request() = apdu; - //std::cout << "z3950_present_request " << *apdu << "\n"; + // sending Z30.50 present request z3950_package.move(); //check successful Z3950 present response @@ -549,21 +612,17 @@ yf::SRUtoZ3950::Impl::z3950_present_request(mp::Package &package, // everything fine, continuing - //std::cout << "z3950_present_request OK\n"; Z_PresentResponse *pr = z3950_gdu->u.z3950->u.presentResponse; Z_SRW_searchRetrieveResponse *sru_res = sru_pdu_res->u.response; - // checking non surrogate dioagnostics in Z3950 present response package - if (pr->records - && pr->records->which == Z_Records_NSD - && pr->records->u.nonSurrogateDiagnostic) - { - //int http_code = - z3950_to_srw_diag(odr_en, sru_res, - pr->records->u.nonSurrogateDiagnostic); + + // checking non surrogate diagnostics in Z3950 present response package + if (!z3950_to_srw_diagnostics_ok(odr_en, sru_pdu_res->u.response, + pr->records)) return false; - } + + // copy all records if existing if (pr->records && pr->records->which == Z_Records_DBOSD) @@ -594,8 +653,8 @@ yf::SRUtoZ3950::Impl::z3950_present_request(mp::Package &package, = pr->records->u.databaseOrSurDiagnostics->records[i]; sru_res->records[i].recordPosition - = odr_intdup(odr_en, - i + *(apdu->u.presentRequest->resultSetStartPoint)); + = odr_intdup(odr_en, + i + *(apdu->u.presentRequest->resultSetStartPoint)); sru_res->records[i].recordPacking = record_packing; @@ -740,6 +799,24 @@ bool yf::SRUtoZ3950::Impl::z3950_build_query(mp::odr &odr_en, Z_Query *z_query, } +bool +yf::SRUtoZ3950::Impl::z3950_to_srw_diagnostics_ok(mp::odr &odr_en, + Z_SRW_searchRetrieveResponse + *sru_res, + Z_Records *records) const +{ + // checking non surrogate diagnostics in Z3950 present response package + if (records + && records->which == Z_Records_NSD + && records->u.nonSurrogateDiagnostic) + { + z3950_to_srw_diag(odr_en, sru_res, + records->u.nonSurrogateDiagnostic); + return false; + } + return true; +} + int yf::SRUtoZ3950::Impl::z3950_to_srw_diag(mp::odr &odr_en, @@ -747,13 +824,11 @@ yf::SRUtoZ3950::Impl::z3950_to_srw_diag(mp::odr &odr_en, Z_DefaultDiagFormat *ddf) const { int bib1_code = *ddf->condition; - if (bib1_code == 109) - return 404; sru_res->num_diagnostics = 1; sru_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(odr_en, sizeof(*sru_res->diagnostics)); yaz_mk_std_diagnostic(odr_en, sru_res->diagnostics, - yaz_diag_bib1_to_srw(*ddf->condition), + yaz_diag_bib1_to_srw(bib1_code), ddf->u.v2Addinfo); return 0; }