metaproxy  1.21.0
filter_zeerex_explain.cpp
Go to the documentation of this file.
1 /* This file is part of Metaproxy.
2  Copyright (C) Index Data
3 
4 Metaproxy is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include "config.hpp"
21 #include <metaproxy/package.hpp>
22 #include <metaproxy/util.hpp>
23 #include "gduutil.hpp"
24 #include "sru_util.hpp"
25 
26 #include <yaz/zgdu.h>
27 #include <yaz/z-core.h>
28 #include <yaz/srw.h>
29 #include <yaz/pquery.h>
30 
31 #include <boost/thread/mutex.hpp>
32 
33 #include <iostream>
34 #include <sstream>
35 #include <string>
36 #include <algorithm>
37 #include <map>
38 
39 namespace mp = metaproxy_1;
40 namespace mp_util = metaproxy_1::util;
41 namespace yf = mp::filter;
42 
43 
44 namespace metaproxy_1 {
45  namespace filter {
47  public:
48  void configure(const xmlNode *xmlnode);
49  void process(metaproxy_1::Package &package);
50  private:
51  std::map<std::string, const xmlNode *> m_database_explain;
52  };
53  }
54 }
55 
56 yf::ZeeRexExplain::ZeeRexExplain() : m_p(new Impl)
57 {
58 }
59 
60 yf::ZeeRexExplain::~ZeeRexExplain()
61 { // must have a destructor because of boost::scoped_ptr
62 }
63 
64 void yf::ZeeRexExplain::configure(const xmlNode *xmlnode, bool test_only,
65  const char *path)
66 {
67  m_p->configure(xmlnode);
68 }
69 
70 void yf::ZeeRexExplain::process(mp::Package &package) const
71 {
72  m_p->process(package);
73 }
74 
75 void yf::ZeeRexExplain::Impl::configure(const xmlNode *confignode)
76 {
77  const xmlNode * dbnode;
78 
79  for (dbnode = confignode->children; dbnode; dbnode = dbnode->next){
80  if (dbnode->type != XML_ELEMENT_NODE)
81  continue;
82 
83  std::string database;
84  mp::xml::check_element_mp(dbnode, "database");
85 
86  for (struct _xmlAttr *attr = dbnode->properties;
87  attr; attr = attr->next){
88 
89  mp::xml::check_attribute(attr, "", "name");
90  database = mp::xml::get_text(attr);
91 
92  std::cout << database << "\n";
93 
94  const xmlNode *explainnode;
95  for (explainnode = dbnode->children;
96  explainnode; explainnode = explainnode->next){
97  if (explainnode->type != XML_ELEMENT_NODE)
98  continue;
99  if (explainnode)
100  break;
101  }
102  // assigning explain node to database name - no check yet
103  m_database_explain.insert(std::make_pair(database, explainnode));
104  }
105  }
106 }
107 
108 
109 void yf::ZeeRexExplain::Impl::process(mp::Package &package)
110 {
111  Z_GDU *zgdu_req = package.request().get();
112 
113  // ignoring all non HTTP_Request packages
114  if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){
115  package.move();
116  return;
117  }
118 
119  // only working on HTTP_Request packages now
120 
121  mp::odr odr_de(ODR_DECODE);
122  Z_SRW_PDU *sru_pdu_req = 0;
123 
124  mp::odr odr_en(ODR_ENCODE);
125  //Z_SRW_PDU *sru_pdu_res = 0;
126  Z_SRW_PDU *sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response);
127 
128  // finding correct SRU database and explain XML node fragment from config
130 
131  const xmlNode *explainnode = 0;
132  std::map<std::string, const xmlNode *>::iterator idbexp;
133  idbexp = m_database_explain.find(sruinfo.database);
134 
135  //std::cout << "Finding " << sruinfo.database << "\n";
136  if (idbexp != m_database_explain.end()){
137  //std::cout << "Found " << idbexp->first << " " << idbexp->second << "\n";
138  explainnode = idbexp->second;
139  }
140  else {
141  // need to emmit error ?? or just let package pass ??
142  //std::cout << "Missed " << sruinfo.database << "\n";
143  package.move();
144  return;
145  }
146 
147 
148  // if SRU package could not be decoded, send minimal explain and
149  // close connection
150 
151  Z_SOAP *soap = 0;
152  char *charset = 0;
153  char *stylesheet = 0;
154  Z_SRW_diagnostic *diagnostic = 0;
155  int num_diagnostic = 0;
156 
157  if (! (sru_pdu_req = mp_util::decode_sru_request(
158  package, odr_de, odr_en,
159  &diagnostic, &num_diagnostic, &soap,
160  charset)))
161  {
162  mp_util::build_sru_explain(package, odr_en, sru_pdu_res,
163  sruinfo, explainnode);
164  mp_util::build_sru_response(package, odr_en, soap,
165  sru_pdu_res, charset, stylesheet);
166  package.session().close();
167  return;
168  }
169 
170 
171  if (sru_pdu_req->which != Z_SRW_explain_request)
172  {
173  // Let pass all other SRU actions
174  package.move();
175  return;
176  }
177  // except valid SRU explain request, construct ZeeRex Explain response
178  else
179  {
180  Z_SRW_explainRequest *er_req = sru_pdu_req->u.explain_request;
181 
182  sru_pdu_res->u.explain_response->diagnostics = diagnostic;
183  sru_pdu_res->u.explain_response->num_diagnostics = num_diagnostic;
184  //mp_util::build_simple_explain(package, odr_en, sru_pdu_res,
185  // sruinfo, er_req);
186  mp_util::build_sru_explain(package, odr_en, sru_pdu_res,
187  sruinfo, explainnode, er_req);
188  mp_util::build_sru_response(package, odr_en, soap,
189  sru_pdu_res, charset, stylesheet);
190  return;
191  }
192 
193  // should never arrive here
194  package.session().close();
195  return;
196 }
197 
198 
199 
200 static mp::filter::Base* filter_creator()
201 {
202  return new mp::filter::ZeeRexExplain;
203 }
204 
205 extern "C" {
206  struct metaproxy_1_filter_struct metaproxy_1_filter_zeerex_explain = {
207  0,
208  "zeerex_explain",
210  };
211 }
212 
213 
214 /*
215  * Local variables:
216  * c-basic-offset: 4
217  * c-file-style: "Stroustrup"
218  * indent-tabs-mode: nil
219  * End:
220  * vim: shiftwidth=4 tabstop=8 expandtab
221  */
222 
void process(metaproxy_1::Package &package)
std::map< std::string, const xmlNode * > m_database_explain
struct metaproxy_1_filter_struct metaproxy_1_filter_zeerex_explain
static mp::filter::Base * filter_creator()
Z_SRW_PDU * decode_sru_request(metaproxy_1::Package &package, metaproxy_1::odr &odr_de, metaproxy_1::odr &odr_en, Z_SRW_diagnostic **diagnostic, int *num_diagnostic, Z_SOAP **soap, char *charset)
SRUServerInfo get_sru_server_info(metaproxy_1::Package &package)
bool build_sru_response(metaproxy_1::Package &package, metaproxy_1::odr &odr_en, Z_SOAP *soap, const Z_SRW_PDU *sru_pdu_res, char *charset, const char *stylesheet)
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)
Definition: sru_util.cpp:94