namespace metaproxy_1 {
namespace filter {
+ class SRUtoZ3950::Frontend : boost::noncopyable {
+ friend class Impl;
+ bool m_in_use;
+ public:
+ Frontend();
+ ~Frontend();
+ };
class SRUtoZ3950::Impl {
public:
void configure(const xmlNode *xmlnode);
void process(metaproxy_1::Package &package);
private:
+ FrontendPtr get_frontend(mp::Package &package);
+ void release_frontend(mp::Package &package);
std::map<std::string, const xmlNode *> m_database_explain;
typedef std::map<std::string, int> ActiveUrlMap;
- boost::mutex m_mutex;
+ boost::mutex m_url_mutex;
boost::condition m_cond_url_ready;
ActiveUrlMap m_active_urls;
+
+
+ boost::mutex m_mutex_session;
+ boost::condition m_cond_session_ready;
+ std::map<mp::Session, FrontendPtr> m_clients;
private:
void sru(metaproxy_1::Package &package, Z_GDU *zgdu_req);
int z3950_build_query(
if (sru_pdu_req->which == Z_SRW_explain_request)
{
Z_SRW_explainRequest *er_req = sru_pdu_req->u.explain_request;
- //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);
}
}
-void yf::SRUtoZ3950::Impl::process(mp::Package &package)
+yf::SRUtoZ3950::Frontend::Frontend() : m_in_use(true)
{
- Z_GDU *zgdu_req = package.request().get();
+}
+
+yf::SRUtoZ3950::Frontend::~Frontend()
+{
+}
+
+
+yf::SRUtoZ3950::FrontendPtr yf::SRUtoZ3950::Impl::get_frontend(
+ mp::Package &package)
+{
+ boost::mutex::scoped_lock lock(m_mutex_session);
- // ignoring all non HTTP_Request packages
- if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request))
+ std::map<mp::Session,yf::SRUtoZ3950::FrontendPtr>::iterator it;
+
+ while (true)
{
- package.move();
- return;
+ it = m_clients.find(package.session());
+ if (it == m_clients.end())
+ break;
+
+ if (!it->second->m_in_use)
+ {
+ it->second->m_in_use = true;
+ return it->second;
+ }
+ m_cond_session_ready.wait(lock);
}
-
- // only working on HTTP_Request packages now
+ FrontendPtr f(new Frontend);
+ m_clients[package.session()] = f;
+ f->m_in_use = true;
+ return f;
+}
- // see if HTTP request is already being executed..
- // we consider only the SRU - GET case..
- if (zgdu_req->u.HTTP_Request->content_len == 0)
+void yf::SRUtoZ3950::Impl::release_frontend(mp::Package &package)
+{
+ boost::mutex::scoped_lock lock(m_mutex_session);
+ std::map<mp::Session,FrontendPtr>::iterator it;
+
+ it = m_clients.find(package.session());
+ if (it != m_clients.end())
{
- const char *path = zgdu_req->u.HTTP_Request->path;
- boost::mutex::scoped_lock lock(m_mutex);
- while (1)
+ if (package.session().is_closed())
{
- ActiveUrlMap::iterator it = m_active_urls.find(path);
- if (it == m_active_urls.end())
- {
- m_active_urls[path] = 1;
- break;
- }
- yaz_log(YLOG_LOG, "Waiting for %s to complete", path);
- m_cond_url_ready.wait(lock);
+ m_clients.erase(it);
}
+ else
+ {
+ it->second->m_in_use = false;
+ }
+ m_cond_session_ready.notify_all();
}
- sru(package, zgdu_req);
- if (zgdu_req->u.HTTP_Request->content_len == 0)
- {
- const char *path = zgdu_req->u.HTTP_Request->path;
- boost::mutex::scoped_lock lock(m_mutex);
+}
- ActiveUrlMap::iterator it = m_active_urls.find(path);
+void yf::SRUtoZ3950::Impl::process(mp::Package &package)
+{
+ FrontendPtr f = get_frontend(package);
+
+ Z_GDU *zgdu_req = package.request().get();
- m_active_urls.erase(it);
- m_cond_url_ready.notify_all();
+ if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request)
+ {
+ if (zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_url_mutex);
+ while (1)
+ {
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+ if (it == m_active_urls.end())
+ {
+ m_active_urls[path] = 1;
+ break;
+ }
+ yaz_log(YLOG_LOG, "Waiting for %s to complete", path);
+ m_cond_url_ready.wait(lock);
+ }
+ }
+ sru(package, zgdu_req);
+ if (zgdu_req && zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_url_mutex);
+
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+
+ m_active_urls.erase(it);
+ m_cond_url_ready.notify_all();
+ }
}
+ release_frontend(package);
}
-
bool
yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package,
mp::odr &odr_en,
return false;
}
-bool
-yf::SRUtoZ3950::Impl::z3950_close_request(mp::Package &package) const
+bool yf::SRUtoZ3950::Impl::z3950_close_request(mp::Package &package) const
{
- // prepare and close Z3950 package
Package z3950_package(package.session(), package.origin());
z3950_package.copy_filter(package);
z3950_package.session().close();
- // set close APDU
- //mp::odr odr_en(ODR_ENCODE);
- //Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_close);
- //z3950_package.request() = apdu;
-
z3950_package.move();
- // check successful close response
- //Z_GDU *z3950_gdu = z3950_package.response().get();
- //if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950
- // && z3950_gdu->u.z3950->which == Z_APDU_close)
- // return true;
-
if (z3950_package.session().is_closed())
{
return true;
Package z3950_package(package.session(), package.origin());
z3950_package.copy_filter(package);
- //add stuff in z3950 apdu
Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_searchRequest);
Z_SearchRequest *z_searchRequest = apdu->u.searchRequest;
= odr_strdup(odr_en, "Default");
}
- // z3950'fy query
Z_Query *z_query = (Z_Query *) odr_malloc(odr_en, sizeof(Z_Query));
z_searchRequest->query = z_query;
z3950_package.request() = apdu;
- // send Z39.50 package off to backend
z3950_package.move();
-
Z_GDU *z3950_gdu = z3950_package.response().get();
- //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
return false;
}
- // everything fine, continuing
Z_SearchResponse *sr = z3950_gdu->u.z3950->u.searchResponse;
- // 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
+ sru_pdu_res->u.response->numberOfRecords
= odr_intdup(odr_en, *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;
}
-bool
-yf::SRUtoZ3950::Impl::z3950_present_request(
+bool yf::SRUtoZ3950::Impl::z3950_present_request(
mp::Package &package,
mp::odr &odr_en,
Z_SRW_PDU *sru_pdu_res,
return true;
}
-int yf::SRUtoZ3950::Impl::z3950_build_query(mp::odr &odr_en, Z_Query *z_query,
- const Z_SRW_searchRetrieveRequest *req
+int yf::SRUtoZ3950::Impl::z3950_build_query(
+ mp::odr &odr_en, Z_Query *z_query,
+ const Z_SRW_searchRetrieveRequest *req
) const
{
if (req->query_type == Z_SRW_query_type_cql)
return YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED;
}
-
-bool
-yf::SRUtoZ3950::Impl::z3950_to_srw_diagnostics_ok(mp::odr &odr_en,
- Z_SRW_searchRetrieveResponse
- *sru_res,
- Z_Records *records) const
+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
return true;
}
-
-int
-yf::SRUtoZ3950::Impl::z3950_to_srw_diag(mp::odr &odr_en,
- Z_SRW_searchRetrieveResponse *sru_res,
- Z_DefaultDiagFormat *ddf) const
+int yf::SRUtoZ3950::Impl::z3950_to_srw_diag(
+ mp::odr &odr_en,
+ Z_SRW_searchRetrieveResponse *sru_res,
+ Z_DefaultDiagFormat *ddf) const
{
int bib1_code = *ddf->condition;
sru_res->num_diagnostics = 1;
return 0;
}
-
-
static mp::filter::Base* filter_creator()
{
return new mp::filter::SRUtoZ3950;