From 2ad2651374674c895ad59b267da6fe2d8665fabd Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 12 Aug 2010 13:08:34 +0200 Subject: [PATCH] SOLR support for ZOOM and yaz-client The SOLR requests and responses (search only) are encoded in the same structures as SRW/SRU, because they are semantically so equal. It also means minimal change to existing software. However, at this time decoding of a SOLR search response must be instructed by the client. Had the SOLR Webservice used a namespace we might have a cleaner model. For ZOOM, option "sru" may be set to "solr" in which case ZOOM will contact a SOLR server with the URL with suffix "/select". So far the following SRU parameters are mapped: query, startRecord, maximumRecords. --- client/client.c | 271 +++++++++++++---------------------------------------- include/yaz/srw.h | 5 + src/Makefile.am | 4 +- src/solr.c | 203 +++++++++++++++++++++++++++++++++++++++ src/sru-p.h | 45 +++++++++ src/srwutil.c | 93 +++++++++--------- src/zoom-c.c | 4 +- src/zoom-p.h | 3 +- src/zoom-sru.c | 16 +++- win/makefile | 1 + 10 files changed, 389 insertions(+), 256 deletions(-) create mode 100644 src/solr.c create mode 100644 src/sru-p.h diff --git a/client/client.c b/client/client.c index e41c9f6..d9a98f8 100644 --- a/client/client.c +++ b/client/client.c @@ -80,7 +80,6 @@ static file_history_t file_history = 0; -static char webservice_type[10]; static char sru_method[10] = "soap"; static char sru_version[10] = "1.2"; static char *codeset = 0; /* character set for output */ @@ -1283,6 +1282,11 @@ static int send_srw_host_path(Z_SRW_PDU *sr, const char *host_port, { yaz_sru_soap_encode(gdu->u.HTTP_Request, sr, out, charset); } + else if (!yaz_matchstr(sru_method, "solr")) + { + yaz_solr_encode(gdu->u.HTTP_Request, sr, out, charset); + } + return send_gdu(gdu); } @@ -1410,43 +1414,6 @@ static int send_SRW_scanRequest(const char *arg, int pos, int num) return send_srw(sr); } -static void encode_SOLR_search(Z_HTTP_Request *hreq, ODR encode, - const char *query) -{ - char *path; - const char *name[10], *value[10]; - char *uri_args; - - name[0] = "q"; - value[0] = query; - name[1] = 0; - - yaz_array_to_uri(&uri_args, encode, (char **) name, (char **) value); - - path = (char *) - odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4); - - hreq->method = "GET"; - - if (strchr(hreq->path, '?')) - sprintf(path, "%s&%s", hreq->path, uri_args); - else - sprintf(path, "%s?%s", hreq->path, uri_args); - hreq->path = path; -} - -static int send_SOLR_searchRequest(const char *arg) -{ - Z_GDU *gdu; - char *path = yaz_encode_sru_dbpath_odr(out, databaseNames[0]); - - gdu = z_get_HTTP_Request_host_path(out, cur_host, path); - - encode_SOLR_search(gdu->u.HTTP_Request, out, arg); - - return send_gdu(gdu); -} - static int send_SRW_searchRequest(const char *arg) { Z_SRW_PDU *sr = 0; @@ -2837,9 +2804,7 @@ static int cmd_sru(const char *arg) } else { - int r; - strcpy(webservice_type, "sru"); - r = sscanf(arg, "%9s %9s", sru_method, sru_version); + int r = sscanf(arg, "%9s %9s", sru_method, sru_version); if (r >= 1) { if (!yaz_matchstr(sru_method, "post")) @@ -2848,40 +2813,19 @@ static int cmd_sru(const char *arg) ; else if (!yaz_matchstr(sru_method, "soap")) ; + else if (!yaz_matchstr(sru_method, "solr")) + ; else { strcpy(sru_method, "soap"); printf("Unknown SRU method: %s\n", arg); - printf("Specify one of POST, GET, SOAP\n"); + printf("Specify one of POST, GET, SOAP, SOLR\n"); } } } return 0; } -static int cmd_webservice(const char *arg) -{ - if (!*arg) - { - printf("Webservice: %s\n", webservice_type); - } - else - { - if (!strcmp(arg, "sru")) - ; - else if (!strcmp(arg, "solr")) - ; - else - { - printf("Unknown webservice type\n"); - return 0; - } - strcpy(webservice_type, arg); - } - return 0; -} - - static int cmd_find(const char *arg) { if (!*arg) @@ -2896,16 +2840,8 @@ static int cmd_find(const char *arg) session_connect(cur_host); if (!conn) return 0; - if (!strcmp(webservice_type, "solr")) - { - if (!send_SOLR_searchRequest(arg)) - return 0; - } - else - { - if (!send_SRW_searchRequest(arg)) - return 0; - } + if (!send_SRW_searchRequest(arg)) + return 0; #else return 0; #endif @@ -4283,8 +4219,6 @@ static void initialize(const char *rc_file) exit(1); } - strcpy(webservice_type, "sru"); - setvbuf(stdout, 0, _IONBF, 0); if (apdu_file) odr_setprint(print, apdu_file); @@ -4417,97 +4351,11 @@ static void handle_srw_scan_response(Z_SRW_scanResponse *res) handle_srw_scan_term(res->terms + i); } -static int decode_SOLR_response(const char *content_buf, int content_len) -{ - xmlDocPtr doc = xmlParseMemory(content_buf, content_len); - int ret = 0; - xmlNodePtr ptr = 0; - Odr_int hits = 0; - Odr_int start = 0; - - if (!doc) - { - ret = -1; - } - if (doc) - { - xmlNodePtr root = xmlDocGetRootElement(doc); - if (!root) - { - ret = -1; - } - else if (strcmp((const char *) root->name, "response")) - { - ret = -1; - } - else - { - /** look for result node */ - for (ptr = root->children; ptr; ptr = ptr->next) - { - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "result")) - break; - } - if (!ptr) - { - ret = -1; - } - } - } - if (ptr) - { /* got result node */ - struct _xmlAttr *attr; - for (attr = ptr->properties; attr; attr = attr->next) - if (attr->children && attr->children->type == XML_TEXT_NODE) - { - if (!strcmp((const char *) attr->name, "numFound")) - { - hits = odr_atoi((const char *) attr->children->content); - } - else if (!strcmp((const char *) attr->name, "start")) - { - start = odr_atoi((const char *) attr->children->content); - } - } - printf("Number of hits: " ODR_INT_PRINTF "\n", hits); - } - if (ptr) - { - xmlNodePtr node; - int offset = 0; - - for (node = ptr->children; node; node = node->next) - { - if (node->type == XML_ELEMENT_NODE) - { - xmlBufferPtr buf = xmlBufferCreate(); - xmlNode *tmp = xmlCopyNode(node, 1); - - printf(ODR_INT_PRINTF "\n", start + offset); - - xmlNodeDump(buf, tmp->doc, tmp, 0, 0); - - xmlFreeNode(tmp); - - fwrite(buf->content, 1, buf->use, stdout); - xmlBufferFree(buf); - offset++; - printf("\n"); - } - } - } - if (doc) - xmlFreeDoc(doc); - return ret; -} - static void http_response(Z_HTTP_Response *hres) { int ret = -1; const char *connection_head = z_HTTP_header_lookup(hres->headers, "Connection"); - if (hres->code != 200) { printf("HTTP Error Status=%d\n", hres->code); @@ -4515,57 +4363,71 @@ static void http_response(Z_HTTP_Response *hres) if (!yaz_srw_check_content_type(hres)) printf("Content type does not appear to be XML\n"); - else if (!strcmp(webservice_type, "solr")) - { - decode_SOLR_response(hres->content_buf, hres->content_len); - } - else if (!strcmp(webservice_type, "sru")) - { - Z_SOAP *soap_package = 0; - ODR o = odr_createmem(ODR_DECODE); - Z_SOAP_Handler soap_handlers[3] = { - {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, - {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, - {0, 0, 0} - }; - ret = z_soap_codec(o, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers); - if (!ret && soap_package->which == Z_SOAP_generic) + else + { + if (!yaz_matchstr(sru_method, "solr")) { - Z_SRW_PDU *sr = (Z_SRW_PDU *) soap_package->u.generic->p; - if (sr->which == Z_SRW_searchRetrieve_response) + Z_SRW_PDU *sr = 0; + ODR o = odr_createmem(ODR_DECODE); + ret = yaz_solr_decode(o, hres, &sr); + + if (ret == 0 && sr->which == Z_SRW_searchRetrieve_response) handle_srw_response(sr->u.response); - else if (sr->which == Z_SRW_explain_response) - handle_srw_explain_response(sr->u.explain_response); - else if (sr->which == Z_SRW_scan_response) - handle_srw_scan_response(sr->u.scan_response); - else if (sr->which == Z_SRW_update_response) - printf("Got update response. Status: %s\n", - sr->u.update_response->operationStatus); else { - printf("Decoding of SRW package failed\n"); + printf("Decoding of SOLR package failed\n"); ret = -1; } - } - else if (soap_package && (soap_package->which == Z_SOAP_fault - || soap_package->which == Z_SOAP_error)) - { - printf("SOAP Fault code %s\n", - soap_package->u.fault->fault_code); - printf("SOAP Fault string %s\n", - soap_package->u.fault->fault_string); - if (soap_package->u.fault->details) - printf("SOAP Details %s\n", - soap_package->u.fault->details); + odr_destroy(o); } else { - printf("z_soap_codec failed. (no SOAP error)\n"); - ret = -1; + Z_SOAP *soap_package = 0; + ODR o = odr_createmem(ODR_DECODE); + Z_SOAP_Handler soap_handlers[3] = { + {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, + {0, 0, 0} + }; + ret = z_soap_codec(o, &soap_package, + &hres->content_buf, &hres->content_len, + soap_handlers); + if (!ret && soap_package->which == Z_SOAP_generic) + { + Z_SRW_PDU *sr = (Z_SRW_PDU *) soap_package->u.generic->p; + if (sr->which == Z_SRW_searchRetrieve_response) + handle_srw_response(sr->u.response); + else if (sr->which == Z_SRW_explain_response) + handle_srw_explain_response(sr->u.explain_response); + else if (sr->which == Z_SRW_scan_response) + handle_srw_scan_response(sr->u.scan_response); + else if (sr->which == Z_SRW_update_response) + printf("Got update response. Status: %s\n", + sr->u.update_response->operationStatus); + else + { + printf("Decoding of SRW package failed\n"); + ret = -1; + } + } + else if (soap_package && (soap_package->which == Z_SOAP_fault + || soap_package->which == Z_SOAP_error)) + { + printf("SOAP Fault code %s\n", + soap_package->u.fault->fault_code); + printf("SOAP Fault string %s\n", + soap_package->u.fault->fault_string); + if (soap_package->u.fault->details) + printf("SOAP Details %s\n", + soap_package->u.fault->details); + } + else + { + printf("z_soap_codec failed. (no SOAP error)\n"); + ret = -1; + } + odr_destroy(o); } - odr_destroy(o); } if (ret) close_session(); /* close session on error */ @@ -5111,7 +4973,6 @@ static struct { {"init", cmd_init, "", NULL,0,NULL}, {"sru", cmd_sru, " ", NULL,0,NULL}, {"url", cmd_url, "", NULL,0,NULL}, - {"webservice", cmd_webservice, "", NULL,0,NULL}, {"exit", cmd_quit, "",NULL,0,NULL}, {0,0,0,0,0,0} }; diff --git a/include/yaz/srw.h b/include/yaz/srw.h index d5e7043..f630a93 100644 --- a/include/yaz/srw.h +++ b/include/yaz/srw.h @@ -271,6 +271,9 @@ YAZ_EXPORT int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, char **charset, Z_SRW_diagnostic **, int *num_diagnostic); +YAZ_EXPORT int yaz_solr_decode(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup); + + YAZ_EXPORT void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d, int *num, int code, const char *addinfo); @@ -297,6 +300,8 @@ YAZ_EXPORT int yaz_sru_post_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, ODR encode, const char *charset); YAZ_EXPORT int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, ODR odr, const char *charset); +YAZ_EXPORT int yaz_solr_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, + ODR encode, const char *charset); YAZ_EXPORT char *yaz_negotiate_sru_version(char *input_ver); diff --git a/src/Makefile.am b/src/Makefile.am index 2c33812..bf7a10e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,8 +90,8 @@ libyaz_la_SOURCES=version.c options.c log.c \ otherinfo.c pquery.c sortspec.c charneg.c initopt.c \ zoom-c.c zoom-z3950.c zoom-sru.c zoom-query.c zoom-record-cache.c \ zoom-event.c \ - record_render.c zoom-socket.c zoom-opt.c zoom-p.h \ - grs1disp.c zgdu.c soap.c srw.c srwutil.c uri.c \ + record_render.c zoom-socket.c zoom-opt.c zoom-p.h sru-p.h \ + grs1disp.c zgdu.c soap.c srw.c srwutil.c uri.c solr.c \ opacdisp.c cclfind.c ccltoken.c cclerrms.c cclqual.c cclptree.c cclp.h \ cclqfile.c cclstr.c cclxmlconfig.c ccl_stop_words.c \ cql.y cqlstdio.c cqltransform.c cqlutil.c xcqlutil.c cqlstring.c rpn2cql.c \ diff --git a/src/solr.c b/src/solr.c new file mode 100644 index 0000000..1fa0d38 --- /dev/null +++ b/src/solr.c @@ -0,0 +1,203 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2010 Index Data + * See the file LICENSE for details. + */ +/** + * \file srwutil.c + * \brief Implements SRW/SRU utilities. + */ + +#include +#include +#include +#include +#include + +#include "sru-p.h" + +#if YAZ_HAVE_XML2 +#include +#include +#endif + +int yaz_solr_decode(ODR o, Z_HTTP_Response *hres, Z_SRW_PDU **pdup) +{ +#if YAZ_HAVE_XML2 + const char *content_buf = hres->content_buf; + int content_len = hres->content_len; + xmlDocPtr doc = xmlParseMemory(content_buf, content_len); + int ret = 0; + xmlNodePtr ptr = 0; + Odr_int start = 0; + Z_SRW_PDU *pdu = yaz_srw_get(o, Z_SRW_searchRetrieve_response); + Z_SRW_searchRetrieveResponse *sr = pdu->u.response; + + if (!doc) + { + ret = -1; + } + if (doc) + { + xmlNodePtr root = xmlDocGetRootElement(doc); + if (!root) + { + ret = -1; + } + else if (strcmp((const char *) root->name, "response")) + { + ret = -1; + } + else + { + /** look for result node */ + for (ptr = root->children; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "result")) + break; + } + if (!ptr) + { + ret = -1; + } + } + } + if (ptr) + { /* got result node */ + struct _xmlAttr *attr; + + for (attr = ptr->properties; attr; attr = attr->next) + if (attr->children && attr->children->type == XML_TEXT_NODE) + { + if (!strcmp((const char *) attr->name, "numFound")) + { + sr->numberOfRecords = + odr_intdup(o, + odr_atoi( + (const char *) attr->children->content)); + } + else if (!strcmp((const char *) attr->name, "start")) + { + start = odr_atoi((const char *) attr->children->content); + } + } + } + if (ptr) + { + xmlNodePtr node; + int offset = 0; + int i = 0; + + sr->num_records = 0; + for (node = ptr->children; node; node = node->next) + if (node->type == XML_ELEMENT_NODE) + sr->num_records++; + + sr->records = odr_malloc(o, sizeof(*sr->records) * sr->num_records); + + for (node = ptr->children; node; node = node->next) + { + if (node->type == XML_ELEMENT_NODE) + { + Z_SRW_record *record = sr->records + i; + xmlBufferPtr buf = xmlBufferCreate(); + xmlNode *tmp = xmlCopyNode(node, 1); + + xmlNodeDump(buf, tmp->doc, tmp, 0, 0); + + xmlFreeNode(tmp); + + record->recordSchema = 0; + record->recordPacking = Z_SRW_recordPacking_XML; + record->recordData_len = buf->use; + record->recordData_buf = odr_malloc(o, buf->use + 1); + memcpy(record->recordData_buf, buf->content, buf->use); + record->recordData_buf[buf->use] = '\0'; + record->recordPosition = odr_intdup(o, start + offset); + + xmlBufferFree(buf); + + offset++; + i++; + } + } + } + if (doc) + xmlFreeDoc(doc); + if (ret == 0) + *pdup = pdu; + return ret; +#else + return -1; +#endif +} + +int yaz_solr_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, + ODR encode, const char *charset) +{ + const char *solr_op = 0; + char *name[30], *value[30]; + char *uri_args; + char *path; + int i = 0; + + z_HTTP_header_add_basic_auth(encode, &hreq->headers, + srw_pdu->username, srw_pdu->password); + + switch (srw_pdu->which) + { + case Z_SRW_searchRetrieve_request: + solr_op = "select"; + + switch(srw_pdu->u.request->query_type) + { + case Z_SRW_query_type_pqf: + yaz_add_name_value_str(encode, name, value, &i, + "q", srw_pdu->u.request->query.pqf); + break; + case Z_SRW_query_type_cql: + yaz_add_name_value_str(encode, name, value, &i, + "q", srw_pdu->u.request->query.cql); + break; + default: + return -1; + } + if (srw_pdu->u.request->startRecord) + { + Odr_int start = *srw_pdu->u.request->startRecord - 1; + yaz_add_name_value_int(encode, name, value, &i, + "start", &start); + } + yaz_add_name_value_int(encode, name, value, &i, + "rows", srw_pdu->u.request->maximumRecords); + break; + default: + return -1; + } + name[i] = 0; + yaz_array_to_uri(&uri_args, encode, name, value); + + hreq->method = "GET"; + + path = (char *) + odr_malloc(encode, strlen(hreq->path) + + strlen(uri_args) + strlen(solr_op) + 4); + + sprintf(path, "%s/%s?%s", hreq->path, solr_op, uri_args); + hreq->path = path; + + z_HTTP_header_add_content_type(encode, &hreq->headers, + "text/xml", charset); + return 0; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/sru-p.h b/src/sru-p.h new file mode 100644 index 0000000..7fd57c4 --- /dev/null +++ b/src/sru-p.h @@ -0,0 +1,45 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2010 Index Data. + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Index Data nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * \file sru-p.h + * \brief SRU private header + */ + +void yaz_add_name_value_str(ODR o, char **name, char **value, int *i, + char *a_name, char *val); + +void yaz_add_name_value_int(ODR o, char **name, char **value, int *i, + char *a_name, Odr_int *val); +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/srwutil.c b/src/srwutil.c index 36d88b6..9e71129 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -12,6 +12,7 @@ #include #include #include +#include "sru-p.h" static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len) { @@ -339,7 +340,7 @@ static int yaz_sru_decode_integer(ODR odr, const char *pname, #endif /** - http://www.loc.gov/z3950/agency/zing/srw/service.html + http://www.loc.gov/z3950/agency/zing/srw/service.html */ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, Z_SOAP **soap_package, ODR decode, char **charset, @@ -352,7 +353,7 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, }; #endif const char *content_type = z_HTTP_header_lookup(hreq->headers, - "Content-Type"); + "Content-Type"); /* SRU GET: ignore content type. @@ -361,9 +362,9 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, */ if (!strcmp(hreq->method, "GET") || - (!strcmp(hreq->method, "POST") && content_type && - !yaz_strcmp_del("application/x-www-form-urlencoded", - content_type, "; "))) + (!strcmp(hreq->method, "POST") && content_type && + !yaz_strcmp_del("application/x-www-form-urlencoded", + content_type, "; "))) { char *db = "Default"; const char *p0 = hreq->path, *p1; @@ -1045,8 +1046,8 @@ int yaz_diag_srw_to_bib1(int code) return 1; } -static void add_val_int(ODR o, char **name, char **value, int *i, - char *a_name, Odr_int *val) +void yaz_add_name_value_int(ODR o, char **name, char **value, int *i, + char *a_name, Odr_int *val) { if (val) { @@ -1057,8 +1058,8 @@ static void add_val_int(ODR o, char **name, char **value, int *i, } } -static void add_val_str(ODR o, char **name, char **value, int *i, - char *a_name, char *val) +void yaz_add_name_value_str(ODR o, char **name, char **value, int *i, + char *a_name, char *val) { if (val) { @@ -1072,7 +1073,7 @@ static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode, char **name, char **value, int max_names) { int i = 0; - add_val_str(encode, name, value, &i, "version", srw_pdu->srw_version); + yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version); name[i] = "operation"; switch(srw_pdu->which) { @@ -1081,16 +1082,16 @@ static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode, switch(srw_pdu->u.request->query_type) { case Z_SRW_query_type_cql: - add_val_str(encode, name, value, &i, "query", - srw_pdu->u.request->query.cql); + yaz_add_name_value_str(encode, name, value, &i, "query", + srw_pdu->u.request->query.cql); break; case Z_SRW_query_type_pqf: - add_val_str(encode, name, value, &i, "x-pquery", - srw_pdu->u.request->query.pqf); + yaz_add_name_value_str(encode, name, value, &i, "x-pquery", + srw_pdu->u.request->query.pqf); break; case Z_SRW_query_type_xcql: - add_val_str(encode, name, value, &i, "x-cql", - srw_pdu->u.request->query.xcql); + yaz_add_name_value_str(encode, name, value, &i, "x-cql", + srw_pdu->u.request->query.xcql); break; } switch(srw_pdu->u.request->sort_type) @@ -1098,29 +1099,29 @@ static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode, case Z_SRW_sort_type_none: break; case Z_SRW_sort_type_sort: - add_val_str(encode, name, value, &i, "sortKeys", - srw_pdu->u.request->sort.sortKeys); + yaz_add_name_value_str(encode, name, value, &i, "sortKeys", + srw_pdu->u.request->sort.sortKeys); break; } - add_val_int(encode, name, value, &i, "startRecord", - srw_pdu->u.request->startRecord); - add_val_int(encode, name, value, &i, "maximumRecords", - srw_pdu->u.request->maximumRecords); - add_val_str(encode, name, value, &i, "recordSchema", - srw_pdu->u.request->recordSchema); - add_val_str(encode, name, value, &i, "recordPacking", - srw_pdu->u.request->recordPacking); - add_val_str(encode, name, value, &i, "recordXPath", - srw_pdu->u.request->recordXPath); - add_val_str(encode, name, value, &i, "stylesheet", - srw_pdu->u.request->stylesheet); - add_val_int(encode, name, value, &i, "resultSetTTL", - srw_pdu->u.request->resultSetTTL); + yaz_add_name_value_int(encode, name, value, &i, "startRecord", + srw_pdu->u.request->startRecord); + yaz_add_name_value_int(encode, name, value, &i, "maximumRecords", + srw_pdu->u.request->maximumRecords); + yaz_add_name_value_str(encode, name, value, &i, "recordSchema", + srw_pdu->u.request->recordSchema); + yaz_add_name_value_str(encode, name, value, &i, "recordPacking", + srw_pdu->u.request->recordPacking); + yaz_add_name_value_str(encode, name, value, &i, "recordXPath", + srw_pdu->u.request->recordXPath); + yaz_add_name_value_str(encode, name, value, &i, "stylesheet", + srw_pdu->u.request->stylesheet); + yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL", + srw_pdu->u.request->resultSetTTL); break; case Z_SRW_explain_request: value[i++] = "explain"; - add_val_str(encode, name, value, &i, "stylesheet", - srw_pdu->u.explain_request->stylesheet); + yaz_add_name_value_str(encode, name, value, &i, "stylesheet", + srw_pdu->u.explain_request->stylesheet); break; case Z_SRW_scan_request: value[i++] = "scan"; @@ -1128,24 +1129,24 @@ static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode, switch(srw_pdu->u.scan_request->query_type) { case Z_SRW_query_type_cql: - add_val_str(encode, name, value, &i, "scanClause", - srw_pdu->u.scan_request->scanClause.cql); + yaz_add_name_value_str(encode, name, value, &i, "scanClause", + srw_pdu->u.scan_request->scanClause.cql); break; case Z_SRW_query_type_pqf: - add_val_str(encode, name, value, &i, "x-pScanClause", - srw_pdu->u.scan_request->scanClause.pqf); + yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause", + srw_pdu->u.scan_request->scanClause.pqf); break; case Z_SRW_query_type_xcql: - add_val_str(encode, name, value, &i, "x-cqlScanClause", - srw_pdu->u.scan_request->scanClause.xcql); + yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause", + srw_pdu->u.scan_request->scanClause.xcql); break; } - add_val_int(encode, name, value, &i, "responsePosition", - srw_pdu->u.scan_request->responsePosition); - add_val_int(encode, name, value, &i, "maximumTerms", - srw_pdu->u.scan_request->maximumTerms); - add_val_str(encode, name, value, &i, "stylesheet", - srw_pdu->u.scan_request->stylesheet); + yaz_add_name_value_int(encode, name, value, &i, "responsePosition", + srw_pdu->u.scan_request->responsePosition); + yaz_add_name_value_int(encode, name, value, &i, "maximumTerms", + srw_pdu->u.scan_request->maximumTerms); + yaz_add_name_value_str(encode, name, value, &i, "stylesheet", + srw_pdu->u.scan_request->stylesheet); break; case Z_SRW_update_request: value[i++] = "update"; diff --git a/src/zoom-c.c b/src/zoom-c.c index cab02e5..70769e0 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -338,6 +338,8 @@ static zoom_sru_mode get_sru_mode_from_string(const char *s) return zoom_sru_get; else if (!yaz_matchstr(s, "post")) return zoom_sru_post; + else if (!yaz_matchstr(s, "solr")) + return zoom_sru_solr; return zoom_sru_error; } @@ -1595,7 +1597,7 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) } if (cret == zoom_complete) { - yaz_log(YLOG_LOG, "removing tasks in handle_http"); + yaz_log(c->log_details, "removing tasks in handle_http"); ZOOM_connection_remove_task(c); } { diff --git a/src/zoom-p.h b/src/zoom-p.h index 1692e5c..b0a39fc 100644 --- a/src/zoom-p.h +++ b/src/zoom-p.h @@ -45,7 +45,8 @@ typedef enum { zoom_sru_error, zoom_sru_soap, zoom_sru_get, - zoom_sru_post + zoom_sru_post, + zoom_sru_solr } zoom_sru_mode; diff --git a/src/zoom-sru.c b/src/zoom-sru.c index 1932f09..144f025 100644 --- a/src/zoom-sru.c +++ b/src/zoom-sru.c @@ -24,7 +24,6 @@ static void set_SRU_error(ZOOM_connection c, Z_SRW_diagnostic *d) #endif - #if YAZ_HAVE_XML2 static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr) { @@ -50,6 +49,10 @@ static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr) { yaz_sru_soap_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset); } + else if (c->sru_mode == zoom_sru_solr) + { + yaz_solr_encode(gdu->u.HTTP_Request, sr, c->odr_out, c->charset); + } if (!z_GDU(c->odr_out, &gdu, 0, 0)) return zoom_complete; if (c->odr_print) @@ -378,7 +381,18 @@ int ZOOM_handle_sru(ZOOM_connection c, Z_HTTP_Response *hres, /* not redirect (normal response) */ if (!yaz_srw_check_content_type(hres)) + { addinfo = "content-type"; + ret = -1; + } + else if (c->sru_mode == zoom_sru_solr) + { + Z_SRW_PDU *sr; + ret = yaz_solr_decode(c->odr_in, hres, &sr); + if (ret == 0) + if (sr->which == Z_SRW_searchRetrieve_response) + *cret = handle_srw_response(c, sr->u.response); + } else { Z_SOAP *soap_package = 0; diff --git a/win/makefile b/win/makefile index 206dfda..cebd865 100644 --- a/win/makefile +++ b/win/makefile @@ -470,6 +470,7 @@ MISC_OBJS= \ $(OBJDIR)\opacdisp.obj \ $(OBJDIR)\zgdu.obj \ $(OBJDIR)\soap.obj \ + $(OBJDIR)\solr.obj \ $(OBJDIR)\srw.obj \ $(OBJDIR)\srwutil.obj \ $(OBJDIR)\zoom-c.obj \ -- 1.7.10.4