more work on SRU explain filters
authorMarc Cromme <marc@indexdata.dk>
Sun, 7 Jan 2007 00:41:18 +0000 (00:41 +0000)
committerMarc Cromme <marc@indexdata.dk>
Sun, 7 Jan 2007 00:41:18 +0000 (00:41 +0000)
let SRU explain packages pass through sru_z3950 filter
catch SRU explain packages in zeerex_explain filter
depreciate build_simple_explain() function
introduced build_sru_explain() function which does it all
introduced SRUServerInfo class used to determine SRU database, host and port _before_ parsing of SRU request did succeed, as one has to know which of multiple databases expain to send in case that SRU request is unparsable
still missing actual dump of XML dom explain from correct database
recognized that splitting SRU explain in zeerex_explain filter and SRU searchRetrieve in sru_z3950 filter is a bad idea, as double work is needed to parse the same explain XML dom info, but for sake of this checkin these are kept separated. planned to move SRU explain to sru_z3950 filter, and use zeerex_explain filter for z3950 packages zeerex explain operation only (maybe making mapping from explain classic to zeerex explain ??)

src/filter_sru_to_z3950.cpp
src/filter_zeerex_explain.cpp
src/sru_util.cpp
src/sru_util.hpp

index 68dbab3..70e2432 100644 (file)
@@ -1,8 +1,8 @@
-/* $Id: filter_sru_to_z3950.cpp,v 1.24 2006-12-28 13:26:06 marc Exp $
+/* $Id: filter_sru_to_z3950.cpp,v 1.25 2007-01-07 00:41:18 marc Exp $
    Copyright (c) 2005-2006, Index Data.
 
    See the LICENSE file for details
- */
+*/
 
 #include "config.hpp"
 #include "filter.hpp"
@@ -125,32 +125,31 @@ void yf::SRUtoZ3950::Impl::process(mp::Package &package) const
     char *charset = 0;
     char *stylesheet = 0;
 
+    mp_util::SRUServerInfo sruinfo = mp_util::get_sru_server_info(package);
+
+
     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_response(package, odr_en, soap, 
-                           sru_pdu_res, charset, stylesheet);
-        package.session().close();
+        //mp_util::build_simple_explain(package, odr_en, sru_pdu_res, sruinfo);
+        //mp_util::build_sru_response(package, odr_en, soap, 
+        //                   sru_pdu_res, charset, stylesheet);
+        //package.session().close();
+        package.move();
         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
     if (sru_pdu_req && sru_pdu_req->which == Z_SRW_explain_request)
     {
-        Z_SRW_explainRequest *er_req = sru_pdu_req->u.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);
+        package.move();
+        return;
     }
 
     // searchRetrieve
index eae42cd..8635ee2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: filter_zeerex_explain.cpp,v 1.2 2007-01-05 12:26:50 marc Exp $
+/* $Id: filter_zeerex_explain.cpp,v 1.3 2007-01-07 00:41:18 marc Exp $
    Copyright (c) 2005-2006, Index Data.
 
    See the LICENSE file for details
@@ -23,6 +23,7 @@
 #include <sstream>
 #include <string>
 #include <algorithm>
+#include <map>
 
 namespace mp = metaproxy_1;
 namespace mp_util = metaproxy_1::util;
@@ -34,8 +35,9 @@ namespace metaproxy_1 {
         class ZeeRexExplain::Impl {
         public:
             void configure(const xmlNode *xmlnode);
-            void process(metaproxy_1::Package &package) const;
+            void process(metaproxy_1::Package &package);
         private:
+            std::map<std::string, const xmlNode *> m_database_explain;
         };
     }
 }
@@ -58,11 +60,41 @@ void yf::ZeeRexExplain::process(mp::Package &package) const
     m_p->process(package);
 }
 
-void yf::ZeeRexExplain::Impl::configure(const xmlNode *xmlnode)
+void yf::ZeeRexExplain::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);
+            
+            std::cout << database << "\n";
+            
+            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::ZeeRexExplain::Impl::process(mp::Package &package) const
+
+void yf::ZeeRexExplain::Impl::process(mp::Package &package)
 {
     Z_GDU *zgdu_req = package.request().get();
 
@@ -81,18 +113,38 @@ void yf::ZeeRexExplain::Impl::process(mp::Package &package) const
     //Z_SRW_PDU *sru_pdu_res = 0;
     Z_SRW_PDU *sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response);
 
-    Z_SOAP *soap = 0;
-    char *charset = 0;
-    char *stylesheet = 0;
+    // finding correct SRU database and explain XML node fragment from config
+    mp_util::SRUServerInfo sruinfo = mp_util::get_sru_server_info(package);
+
+    const xmlNode *explainnode = 0;
+    std::map<std::string, const xmlNode *>::iterator idbexp;
+    idbexp = m_database_explain.find(sruinfo.database);
 
+    //std::cout << "Finding " << sruinfo.database << "\n";
+    if (idbexp != m_database_explain.end()){
+        //std::cout << "Found " << idbexp->first << " " << idbexp->second << "\n";
+        explainnode = idbexp->second;
+    }
+    else {
+        // need to emmit error ?? or just let package pass ??
+        //std::cout << "Missed " << sruinfo.database << "\n";
+        package.move();
+        return;
+    }
+    
 
     // if SRU package could not be decoded, send minimal explain and
     // close connection
+
+    Z_SOAP *soap = 0;
+    char *charset = 0;
+    char *stylesheet = 0;
     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();
@@ -108,12 +160,12 @@ void yf::ZeeRexExplain::Impl::process(mp::Package &package) const
     // except valid SRU explain request, construct ZeeRex Explain response
     else {
         Z_SRW_explainRequest *er_req = sru_pdu_req->u.explain_request;
-
-        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;
     }
 
index 4b46ac9..e116592 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sru_util.cpp,v 1.4 2007-01-05 12:26:50 marc Exp $
+/* $Id: sru_util.cpp,v 1.5 2007-01-07 00:41:18 marc Exp $
    Copyright (c) 2005-2006, Index Data.
 
    See the LICENSE file for details
@@ -18,7 +18,7 @@ namespace mp = metaproxy_1;
 // Doxygen doesn't like mp::gdu, so we use this instead
 namespace mp_util = metaproxy_1::util;
 
-
+const std::string xmlns_explain("http://explain.z3950.org/dtd/2.0/");
 
 bool mp_util::build_sru_debug_package(mp::Package &package)
 {
@@ -35,21 +35,18 @@ bool mp_util::build_sru_debug_package(mp::Package &package)
     return false;
 }
 
-void mp_util::get_sru_server_info(mp::Package &package, 
-                                   Z_SRW_explainRequest 
-                                   const *er_req) 
+mp_util::SRUServerInfo mp_util::get_sru_server_info(mp::Package &package)
+    //Z_SRW_explainRequest const *er_req) 
 {
-
-    SRUServerInfo sruinfo;
+    mp_util::SRUServerInfo sruinfo;
 
     // getting database info
-    std::string database("Default");
-    if (er_req && er_req->database)
-        database = er_req->database;
+    //if (er_req && er_req->database)
+    //    sruinfo.database = er_req->database;
 
     // getting host and port info
-    std::string host = package.origin().listen_host();
-    std::string port = mp_util::to_string(package.origin().listen_port());
+    sruinfo.host = package.origin().listen_host();
+    sruinfo.port = mp_util::to_string(package.origin().listen_port());
 
     // overwriting host and port info if set from HTTP Host header
     Z_GDU *zgdu_req = package.request().get();
@@ -58,76 +55,117 @@ void mp_util::get_sru_server_info(mp::Package &package,
         Z_HTTP_Request* http_req =  zgdu_req->u.HTTP_Request;
         if (http_req)
         {
+
+            //std::string http_method = http_req->method;
+            //std::string http_version = http_req->version;
+            std::string http_path = http_req->path;
+            if (http_path.size() > 1)
+                sruinfo.database.assign(http_path, 1, std::string::npos);
+
             std::string http_host_address
                 = mp_util::http_header_value(http_req->headers, "Host");
 
             std::string::size_type i = http_host_address.rfind(":");
             if (i != std::string::npos)
             {
-                host.assign(http_host_address, 0, i);
-                port.assign(http_host_address, i + 1, std::string::npos);
+                sruinfo.host.assign(http_host_address, 0, i);
+                sruinfo.port.assign(http_host_address, i + 1, 
+                                    std::string::npos);
             }
         }
     }
-}
+    
+    //std::cout << "sruinfo.database " << sruinfo.database << "\n";
+    //std::cout << "sruinfo.host " << sruinfo.host << "\n";
+    //std::cout << "sruinfo.port " << sruinfo.port << "\n";
 
+    return sruinfo;
+}
 
-bool mp_util::build_simple_explain(mp::Package &package, 
-                                   mp::odr &odr_en,
-                                   Z_SRW_PDU *sru_pdu_res,
-                                   Z_SRW_explainRequest 
-                                   const *er_req) 
-{
-    // z3950'fy recordPacking
-    int record_packing = Z_SRW_recordPacking_XML;
-    if (er_req && er_req->recordPacking && 's' == *(er_req->recordPacking))
-        record_packing = Z_SRW_recordPacking_string;
 
-    // getting database info
-    std::string database("Default");
-    if (er_req && er_req->database)
-        database = er_req->database;
+// bool mp_util::build_simple_explain(mp::Package &package, 
+//                                    mp::odr &odr_en,
+//                                    Z_SRW_PDU *sru_pdu_res,
+//                                    SRUServerInfo sruinfo,
+//                                    Z_SRW_explainRequest const *er_req) 
+// {
+//     // z3950'fy recordPacking
+//     int record_packing = Z_SRW_recordPacking_XML;
+//     if (er_req && er_req->recordPacking && 's' == *(er_req->recordPacking))
+//         record_packing = Z_SRW_recordPacking_string;
+
+//     // building SRU explain record
+//     std::string explain_xml 
+//         = mp_util::to_string(
+//             "<explain  xmlns=\"" + xmlns_explain + "\">\n"
+//             "  <serverInfo protocol='SRU'>\n"
+//             "    <host>")
+//         + sruinfo.host
+//         + mp_util::to_string("</host>\n"
+//             "    <port>")
+//         + sruinfo.port
+//         + mp_util::to_string("</port>\n"
+//             "    <database>")
+//         + sruinfo.database
+//         + mp_util::to_string("</database>\n"
+//             "  </serverInfo>\n"
+//             "</explain>\n");
+    
+    
+//     // preparing explain record insert
+//     Z_SRW_explainResponse *sru_res = sru_pdu_res->u.explain_response;
+    
+//     // inserting one and only explain record
+    
+//     sru_res->record.recordPosition = odr_intdup(odr_en, 1);
+//     sru_res->record.recordPacking = record_packing;
+//     sru_res->record.recordSchema = (char *)xmlns_explain.c_str();
+//     sru_res->record.recordData_len = 1 + explain_xml.size();
+//     sru_res->record.recordData_buf
+//         = odr_strdupn(odr_en, (const char *)explain_xml.c_str(), 
+//                       1 + explain_xml.size());
 
-    // getting host and port info
-    std::string host = package.origin().listen_host();
-    std::string port = mp_util::to_string(package.origin().listen_port());
+//     return true;
+// };
 
-    // overwriting host and port info if set from HTTP Host header
-    Z_GDU *zgdu_req = package.request().get();
-    if  (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request)
-    {
-        Z_HTTP_Request* http_req =  zgdu_req->u.HTTP_Request;
-        if (http_req)
-        {
-            std::string http_host_address
-                = mp_util::http_header_value(http_req->headers, "Host");
+        
+bool mp_util::build_sru_explain(metaproxy_1::Package &package, 
+                                metaproxy_1::odr &odr_en,
+                                Z_SRW_PDU *sru_pdu_res,
+                                SRUServerInfo sruinfo,
+                                const xmlNode *explain,
+                                Z_SRW_explainRequest const *er_req)
+{
 
-            std::string::size_type i = http_host_address.rfind(":");
-            if (i != std::string::npos)
-            {
-                host.assign(http_host_address, 0, i);
-                port.assign(http_host_address, i + 1, std::string::npos);
-            }
-        }
+    // building SRU explain record
+    std::string explain_xml;    
+
+    if (explain == 0){
+        explain_xml 
+            = mp_util::to_string(
+                "<explain  xmlns=\"" + xmlns_explain + "\">\n"
+                "  <serverInfo protocol='SRU'>\n"
+                "    <host>")
+            + sruinfo.host
+            + mp_util::to_string("</host>\n"
+                                 "    <port>")
+            + sruinfo.port
+            + mp_util::to_string("</port>\n"
+                                 "    <database>")
+            + sruinfo.database
+            + mp_util::to_string("</database>\n"
+                                 "  </serverInfo>\n"
+                                 "</explain>\n");
+    }
+    else {
+        explain_xml = "<need_to_dump_XML_dom_tree/>";
     }
 
-    // building SRU explain record
-    std::string explain_xml 
-        = mp_util::to_string(
-            "<explain  xmlns=\"http://explain.z3950.org/dtd/2.0/\">\n"
-            "  <serverInfo protocol='SRU'>\n"
-            "    <host>")
-        + host
-        + mp_util::to_string("</host>\n"
-            "    <port>")
-        + port
-        + mp_util::to_string("</port>\n"
-            "    <database>")
-        + database
-        + mp_util::to_string("</database>\n"
-            "  </serverInfo>\n"
-            "</explain>\n");
-    
+
+    // z3950'fy recordPacking
+    int record_packing = Z_SRW_recordPacking_XML;
+    if (er_req && er_req->recordPacking && 's' == *(er_req->recordPacking))
+        record_packing = Z_SRW_recordPacking_string;    
     
     // preparing explain record insert
     Z_SRW_explainResponse *sru_res = sru_pdu_res->u.explain_response;
@@ -136,7 +174,7 @@ bool mp_util::build_simple_explain(mp::Package &package,
     
     sru_res->record.recordPosition = odr_intdup(odr_en, 1);
     sru_res->record.recordPacking = record_packing;
-    sru_res->record.recordSchema = "http://explain.z3950.org/dtd/2.0/";
+    sru_res->record.recordSchema = (char *)xmlns_explain.c_str();
     sru_res->record.recordData_len = 1 + explain_xml.size();
     sru_res->record.recordData_buf
         = odr_strdupn(odr_en, (const char *)explain_xml.c_str(), 
index 323ea4a..ab20f4e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sru_util.hpp,v 1.5 2007-01-05 12:26:50 marc Exp $
+/* $Id: sru_util.hpp,v 1.6 2007-01-07 00:41:18 marc Exp $
 -   Copyright (c) 2005-2006, Index Data.
 
    See the LICENSE file for details
@@ -27,6 +27,8 @@ namespace std
 namespace metaproxy_1 {
     namespace util  {
 
+        class SRUServerInfo;
+
         // std::string sru_protocol(const Z_HTTP_Request &http_req);
         // std::string debug_http(const Z_HTTP_Request &http_req);
         // void http_response(mp::Package &package, 
@@ -35,14 +37,22 @@ namespace metaproxy_1 {
 
         bool build_sru_debug_package(metaproxy_1::Package &package);
 
-        void get_sru_server_info(metaproxy_1::Package &package, 
-                                 Z_SRW_explainRequest 
-                                 const *er_req);
+        SRUServerInfo get_sru_server_info(metaproxy_1::Package &package);
+                                          // Z_SRW_explainRequest 
+                                          //const *er_req);
+        
+//         bool build_simple_explain(metaproxy_1::Package &package, 
+//                                   metaproxy_1::odr &odr_en,
+//                                   Z_SRW_PDU *sru_pdu_res,
+//                                   SRUServerInfo sruinfo,
+//                                   Z_SRW_explainRequest const *er_req = 0);
         
-        bool build_simple_explain(metaproxy_1::Package &package, 
-                                  metaproxy_1::odr &odr_en,
-                                  Z_SRW_PDU *sru_pdu_res,
-                                  Z_SRW_explainRequest const *er_req);
+        bool build_sru_explain(metaproxy_1::Package &package, 
+                               metaproxy_1::odr &odr_en,
+                               Z_SRW_PDU *sru_pdu_res,
+                               SRUServerInfo sruinfo,
+                               const xmlNode *explain = 0,
+                               Z_SRW_explainRequest const *er_req = 0);
         
         bool build_sru_response(metaproxy_1::Package &package, 
                                 metaproxy_1::odr &odr_en,