Resolve
authorMike Taylor <mike@indexdata.com>
Mon, 31 Oct 2011 17:08:38 +0000 (17:08 +0000)
committerMike Taylor <mike@indexdata.com>
Mon, 31 Oct 2011 17:08:38 +0000 (17:08 +0000)
45 files changed:
NEWS
configure.ac
debian/changelog
debian/control
debian/rules
doc/Makefile.am
doc/auth_simple.xml
doc/backend_test.xml
doc/book.xml
doc/bounce.xml
doc/cgi.xml
doc/cql_rpn.xml
doc/frontend_net.xml
doc/http_file.xml
doc/limit.xml
doc/load_balance.xml
doc/log.xml
doc/metaproxy.xml
doc/multi.xml
doc/query_rewrite.xml
doc/record_transform.xml
doc/session_shared.xml
doc/sru_z3950.xml
doc/template.xml
doc/virt_db.xml
doc/z3950_client.xml
doc/zeerex_explain.xml
doc/zoom.xml
etc/config-zoom.xml
include/metaproxy/origin.hpp
include/metaproxy/package.hpp
metaproxy.spec
src/filter_bounce.cpp
src/filter_load_balance.cpp
src/filter_session_shared.cpp
src/filter_sru_to_z3950.cpp
src/filter_zoom.cpp
src/origin.cpp
src/package.cpp
src/router_flexml.cpp
src/sru_util.cpp
src/torus.cpp
src/util.cpp
win/makefile
xml/schema/filter_zoom.rnc

diff --git a/NEWS b/NEWS
index a5a12ca..a0fdc05 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,33 @@
+--- 1.3.13 2011/10/26
+
+Fix Origin class assigment method; was removd by mistake in 1.3.12.
+
+--- 1.3.12 2011/10/26
+
+zoom: database args x-name=value are passed through to backend database.
+
+SRU filter: user may specify session ID that is passed to log entries
+that follows. It is specified by using x-session-id in the SRU arguments.
+
+zoom: fix null pointer reference which would occur for bad url parameter
+inside "torus" or if url was not given.
+
+--- 1.3.11 2011/09/09
+Fix bug in filter session_shared where sessions would not expire
+properly (session ttl). This in turn could make the target close the
+connection before expected and session_shared would return diagnostic
+2: system temporarily available.
+
+--- 1.3.10 2011/09/09
+
+zoom: new target profile setting: sortmap_field. If sortmap_field is given
+the field is mapped to the value for the sortmap. Values not matching
+sortmap_field are passed verbatim.
+  
+zoom: new target profile setting: sortStrategy. One of: "z3950", "type7",
+"cql", "sru11" or "embed". The "embed" chooses type-7 or CQL sortby
+depending on whether RPN or CQL is actually sent to the target.
+
 --- 1.3.9 2011/08/25
 
 zoom: urlRecipe result is stored in <pz:metadata type="generated-url">.
index a1445a8..1cc3dcf 100644 (file)
@@ -3,7 +3,7 @@
 
 # Autoconf and automake setup
 AC_PREREQ([2.60])
-AC_INIT([metaproxy],[1.3.9],[metaproxy-help@indexdata.dk])
+AC_INIT([metaproxy],[1.3.13],[metaproxy-help@indexdata.dk])
 
 AC_CONFIG_HEADERS([src/config.hpp])
 
@@ -40,8 +40,20 @@ YAZPP_INIT([threads],[1.2.7])
 if test -z "$YAZPPLIB"; then
     AC_MSG_ERROR([YAZ++ development libraries missing])
 fi
-YAZ_DOC
 CPPFLAGS="$YAZPPINC $CPPFLAGS"
+AC_MSG_CHECKING([if YAZ is version 4.2.14 or later])
+AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM([[#include <yaz/yaz-version.h>]],
+                         [[
+#if YAZ_VERSIONL < 0x4020e
+#error too old
+#endif
+]])],
+        [AC_MSG_RESULT([yes])],
+        [AC_MSG_RESULT([no])
+        AC_MSG_ERROR([newer version of YAZ required])]
+)
+YAZ_DOC
 
 ID_BOOST([thread test regex],[1.33])
 if test -z "${BOOST_THREAD_LIB}"; then
index 1f44519..cdd40cd 100644 (file)
@@ -1,3 +1,27 @@
+metaproxy (1.3.13-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Wed, 26 Oct 2011 20:29:14 +0200
+
+metaproxy (1.3.12-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Wed, 26 Oct 2011 14:00:22 +0200
+
+metaproxy (1.3.11-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Fri, 09 Sep 2011 11:06:56 +0200
+
+metaproxy (1.3.10-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Fri, 09 Sep 2011 09:57:00 +0200
+
 metaproxy (1.3.9-1indexdata) unstable; urgency=low
 
   * Upstream.
index ec5f6b8..fa629bf 100644 (file)
@@ -4,7 +4,7 @@ Standards-Version: 3.6.2
 Maintainer: Adam Dickmeiss <adam@indexdata.dk>
 Priority: extra
 Build-Depends: debhelper (>= 4),
-       libyaz4-dev (>= 4.2.8),
+       libyaz4-dev (>= 4.2.14),
        libyazpp4-dev (>= 1.2.7),
        libxslt1-dev,
        libboost-dev,
index 66682a3..7ab9436 100755 (executable)
@@ -101,7 +101,7 @@ binary-arch: build install
        dh_fixperms
 #      dh_perl
 #      dh_python
-       dh_makeshlibs -V 'libmetaproxy4 (>= 1.2.9)'
+       dh_makeshlibs -V 'libmetaproxy4 (>= 1.3.12)'
        dh_installdeb
        dh_shlibdeps  -l debian/libmetaproxy4/usr/lib
        dh_gencontrol
index 13d5b15..cdaadc6 100644 (file)
@@ -104,7 +104,7 @@ multi.png: multi.svg
        unset DISPLAY; ${INKSCAPE} --export-png=$@ --export-area=0:0:1050:500 $?
 
 multi.eps: multi.svg
-       unset DISPLAY; ${INKSCAPE} --export-eps=$@ --export-bbox-page $?
+       unset DISPLAY; ${INKSCAPE} --export-eps=$@ --export-area-page $?
 
 .eps.pdf:
        epstopdf -hires $?
index 6ea6881..4ab7cb8 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 1b3de80..f541b8b 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 566a9ee..9c30be4 100644 (file)
       <para>
        The popular C++ library. Initial versions of Metaproxy
        was built with 1.32 but this is no longer supported.
-       Metaproxy is known to work with Boost version 1.33 through 1.38.
+       Metaproxy is known to work with Boost version 1.33 through 1.46.
       </para>
      </listitem>
     </varlistentry>
   <para>
    We have successfully built Metaproxy using the compilers
    <ulink url="&url.gcc;">GCC</ulink> version 4.0 and
-   <ulink url="&url.vstudio;">Microsoft Visual Studio</ulink> 2003/2005.
+   <ulink url="&url.vstudio;">Microsoft Visual Studio</ulink> 2003/2005/2008.
   </para>
 
   <section id="installation.unix">
     <screen>
      gunzip -c boost-version.tar.gz|tar xf -
      cd boost-version
-     ./configure --with-libraries=thread,test --with-toolset=gcc
+     ./configure --with-libraries=thread,test,regex --with-toolset=gcc
      make
      su
      make install
      However, under the hood bjam is used. You can invoke that with
     </para>
     <screen>
-     ./bjam --toolset=gcc --with-thread --with-test stage
+     ./bjam --toolset=gcc --with-thread --with-test --with-regex stage
     </screen>
     <para>
      Replace <literal>stage</literal> with <literal>clean</literal> /
    <para>
     There is currently no official Debian package for YAZ++.
     And the official Debian package for YAZ is probably too old.
-    But Index Data bulds "new" versions of those for Debian (i386 only).
+    But Index Data builds "new" versions of those for Debian (i386, amd64 only).
    </para>
    <para>
     Update the <filename>/etc/apt/sources.list</filename>
     apt-get install libboost-dev
     apt-get install libboost-thread-dev
     apt-get install libboost-test-dev
+    apt-get install libboost-regex-dev
    </screen>
    <para>
     With these packages installed, the usual configure + make
    <para>
     Metaproxy can be compiled with Microsoft
     <ulink url="&url.vstudio;">Visual Studio</ulink>.
-    Versions 2003 (C 7.1), 2005 (C 8.0) and 2008 (C 9.0) is known to work.
+    Versions 2003 (C 7.1), 2005 (C 8.0) and 2008 (C 9.0) are known to work.
    </para>
    <section id="installation.windows.boost">
     <title>Boost</title>
     <title>YAZ++</title>
     <para>
      Get <ulink url="&url.yazplusplus;">YAZ++</ulink> as well.
-     Version 1.1.0 or later is required.
+     Version 1.2.7 or later is required.
     </para>
     <para>
      YAZ++ includes NMAKE makefiles, similar to those found in the
@@ -2096,17 +2097,9 @@ Z>
  &gpl2;
 </book>
 
- <!-- Keep this comment at the end of the file
- Local variables:
- mode: sgml
- sgml-omittag:t
- sgml-shorttag:t
- sgml-minimize-attributes:nil
- sgml-always-quote-attributes:t
- sgml-indent-step:1
- sgml-indent-data:t
- sgml-parent-document: nil
- sgml-local-catalogs: nil
- sgml-namecase-general:t
- End:
- -->
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: nxml
+nxml-child-indent: 1
+End:
+-->
index 57f5a66..34c4171 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index f8c3cdf..b5a9756 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index f60c0a6..1744f4c 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 702de7c..9d8cdca 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index b12a4c0..3b3078b 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index dd48d4b..a39469f 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index fd8867e..ad66c5a 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 86e6b0d..83266d6 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 09ca3fe..a2ef803 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 091862d..cf34cd2 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 4148668..a3b0bc7 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 6465b42..9d20a30 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index e903343..a5d5451 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 3fef9a3..2e14946 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 633c7a5..484ad8f 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index d662688..35c43a6 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 0166e4e..68cb126 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 737b4f4..4496a18 100644 (file)
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index c6a09e9..4835356 100644 (file)
@@ -9,7 +9,7 @@
   <productname>Metaproxy</productname>
   <info><orgname>Index Data</orgname></info>
  </refentryinfo>
-
  <refmeta>
   <refentrytitle>zoom</refentrytitle>
   <manvolnum>3mp</manvolnum>
   <refpurpose>Metaproxy ZOOM Module</refpurpose>
  </refnamediv>
  
- <refsect1><title>DESCRIPTION</title>
+ <refsect1>
+  <title>DESCRIPTION</title>
   <para>
    This filter implements a generic client based on
    <ulink url="&url.yaz.zoom;">ZOOM</ulink> of YAZ.
    The client implements the protocols that ZOOM C does: Z39.50, SRU
    (GET, POST, SOAP) and SOLR .
   </para>
-
+  
   <para>
    This filter only deals with Z39.50 on input. The following services
    are supported: init, search, present and close. The backend target
 
  </refsect1>
 
- <refsect1><title>CONFIGURATION</title>
-   <para>
-     The configuration consists of four parts: <literal>torus</literal>,
-     <literal>fieldmap</literal>, <literal>cclmap</literal>
-     and <literal>log</literal>.
-   </para>
-   <refsect2><title>torus</title>
-     <para>
-       The <literal>torus</literal> element specifies target profiles
-       and takes the following content:
-     </para>
-     <variablelist>
-       <varlistentry>
-        <term>attribute <literal>url</literal></term>
-        <listitem>
-          <para>
-            URL of Web service to be used to fetch target profile
-            for a given database (udb). The special sequence
-            <literal>%db</literal> of the URL is replaced by the
-            actual database specified as part of Search.
-          </para>
-        </listitem>
-       </varlistentry>
-       <varlistentry>
-        <term>attribute <literal>proxy</literal></term>
-        <listitem>
-          <para>
-            HTTP proxy to bse used for fetching target profiles.
-          </para>
-        </listitem>
-       </varlistentry>
-       <varlistentry>
-        <term>attribute <literal>xsldir</literal></term>
-        <listitem>
-          <para>
-            Directory that is searched for XSL stylesheets. Stylesheets
-            are specified in the target profile by the
-            <literal>transform</literal> element.
-          </para>
-        </listitem>
-       </varlistentry>
-       <varlistentry>
-        <term>attribute <literal>element_transform</literal></term>
-        <listitem>
-          <para>
-            Specifies the element that triggers retrieval and transform using
-            the parameters elementSet, recordEncoding, requestSyntax, transform
-            from the target profile. Default value
-            is "pz2", due to the fact that for historical reasons the
-            common format is that used in Pazpar2.
-          </para>
-        </listitem>
-       </varlistentry>
-       <varlistentry>
-        <term>attribute <literal>element_raw</literal></term>
-        <listitem>
-          <para>
-            Specifies an element that triggers retrieval using the
-            parameters elementSet, recordEncoding, requestSyntax from the
-            target profile. Same actions as for element_transform, but without
-            the XSL transform. Useful for debugging.
-            The default value is "raw".
-          </para>
-        </listitem>
-       </varlistentry>
-       <varlistentry>
-        <term>element <literal>records</literal></term>
-        <listitem>
-          <para>
-            Local target profiles. This element may includes zero or
-            more <literal>record</literal> elements (one per target
-            profile). See section TARGET PROFILE.
-          </para>
-        </listitem>
-       </varlistentry>
-     </variablelist>
-   </refsect2>
-   <refsect2><title>fieldmap</title>
-     <para>
-       The <literal>fieldmap</literal> may be specified zero or more times and
-       specifies the map from CQL fields to CCL fields and takes the
-       following content:
-     </para>
-     <variablelist>
-       <varlistentry>
-        <term>attribute <literal>cql</literal></term>
-        <listitem>
-          <para>
-            CQL field that we are mapping "from".
-          </para>
-        </listitem>
-       </varlistentry>
-       <varlistentry>
-        <term>attribute <literal>ccl</literal></term>
-        <listitem>
-          <para>
-            CCL field that we are mapping "to".
-          </para>
-        </listitem>
-       </varlistentry>
-     </variablelist>
-   </refsect2>
-   <refsect2><title>cclmap</title>
-     <para>
-       The third part of the configuration consists of zero or more
-       <literal>cclmap</literal> elements that specifies
-       <emphasis>base</emphasis> CCL profile to be used for all targets.
-       This configuration, thus, will be combined with cclmap-definitions
-       from the target profile.
-     </para>
-   </refsect2>
-   <refsect2><title>log</title>
-     <para>
-       The <literal>log</literal> element controls logging for the
-       ZOOM filter.
-     </para>
-     <variablelist>
-       <varlistentry>
-        <term>attribute <literal>apdu</literal></term>
-        <listitem>
-          <para>
-            If the value of apdu is "true", then protocol packages
-            (APDUs and HTTP packages) from the ZOOM filter will be
-            logged to the yaz_log system. A value of "false" will
-            not perform logging of protocol packages (the default
-            behavior).
-          </para>
-        </listitem>
-       </varlistentry>
-     </variablelist>
-   </refsect2>
- </refsect1>
- <refsect1><title>QUERY HANDLING</title>
-   <para>
-     The ZOOM filter accepts three query types: RPN(Type-1), CCL and
-     CQL.
-   </para>
-   <para>
-     Queries are converted in two separate steps. In the first step
-     the input query is converted to RPN/Type-1. This is always
-     the common internal format between step 1 and step 2.
-     In step 2 the query is converted to the native query type of the target.
-   </para>
+ <refsect1>
+  <title>CONFIGURATION</title>
+  <para>
+   The configuration consists of five parts: <literal>torus</literal>,
+   <literal>fieldmap</literal>, <literal>cclmap</literal>,
+   <literal>contentProxy</literal> and <literal>log</literal>.
+  </para>
+  <refsect2>
+   <title>torus</title>
    <para>
-     Step 1: for RPN, the query is passed unmodified to the target.
+    The <literal>torus</literal> element specifies target profiles
+    and takes the following content:
    </para>
+   <variablelist>
+    <varlistentry>
+     <term>attribute <literal>url</literal></term>
+     <listitem>
+      <para>
+       URL of Web service to be used to fetch target profile
+       for a given database (udb). The special sequence
+       <literal>%db</literal> of the URL is replaced by the
+       actual database specified as part of Search.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>proxy</literal></term>
+     <listitem>
+      <para>
+       HTTP proxy to bse used for fetching target profiles.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>xsldir</literal></term>
+     <listitem>
+      <para>
+       Directory that is searched for XSL stylesheets. Stylesheets
+       are specified in the target profile by the
+       <literal>transform</literal> element.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>element_transform</literal></term>
+     <listitem>
+      <para>
+       Specifies the element that triggers retrieval and transform using
+       the parameters elementSet, recordEncoding, requestSyntax, transform
+       from the target profile. Default value
+       is "pz2", due to the fact that for historical reasons the
+       common format is that used in Pazpar2.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>element_raw</literal></term>
+     <listitem>
+      <para>
+       Specifies an element that triggers retrieval using the
+       parameters elementSet, recordEncoding, requestSyntax from the
+       target profile. Same actions as for element_transform, but without
+       the XSL transform. Useful for debugging.
+       The default value is "raw".
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>element <literal>records</literal></term>
+     <listitem>
+      <para>
+       Local target profiles. This element may includes zero or
+       more <literal>record</literal> elements (one per target
+       profile). See section TARGET PROFILE.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </refsect2>
+  <refsect2 id="fieldmap">
+   <title>fieldmap</title>
    <para>
-     Step 1: for CCL, the query is converted to RPN via
-     <literal>cclmap</literal> elements part of the target profile.
+    The <literal>fieldmap</literal> may be specified zero or more times and
+    specifies the map from CQL fields to CCL fields and takes the
+    following content:
    </para>
+   <variablelist>
+    <varlistentry>
+     <term>attribute <literal>cql</literal></term>
+     <listitem>
+      <para>
+       CQL field that we are mapping "from".
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>ccl</literal></term>
+     <listitem>
+      <para>
+       CCL field that we are mapping "to".
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </refsect2>
+  <refsect2 id="cclmap_base">
+   <title>cclmap</title>
    <para>
-     Step 1: For CQL, the query is converted to CCL. The mappings of
-     CQL fields to CCL fields are handled by <literal>fieldmap</literal>
-     elements as part of the target profile. The resulting query, CCL,
-     is the converted to RPN using the schema mentioned earlier (via
-     <literal>cclmap</literal>).
+    The third part of the configuration consists of zero or more
+    <literal>cclmap</literal> elements that specifies
+    <emphasis>base</emphasis> CCL profile to be used for all targets.
+    This configuration, thus, will be combined with cclmap-definitions
+    from the target profile.
    </para>
+  </refsect2>
+  <refsect2>
+   <title>contentProxy</title>
    <para>
-     Step 2: If the target is Z39.50-based, it is passed verbatim (RPN).
-     If the target is SRU-based, the RPN will be converted to CQL.
-     If the target is SOLR-based, the RPN will be converted to SOLR's query
-     type.
+    The <literal>contentProxy</literal> element controls content proxy'in.
+    This section
+    is optional and must only be defined if content proxy'ing is enabled.
    </para>
- </refsect1>
-
- <refsect1><title>TARGET PROFILE</title>
+   <variablelist>
+    <varlistentry>
+     <term>attribute <literal>server</literal></term>
+     <listitem>
+      <para>
+       Specifies the content proxy host. The host is of the form
+       host[:port]. That is without a method (such as HTTP) and optional
+       port number.
+      </para>
+     </listitem>
+    </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>tmp_file</literal></term>
+     <listitem>
+      <para>
+       Specifies a filename of a session file for content proxy'ing. The
+       file should be an absolute filename that includes
+       <literal>XXXXXX</literal> which is replaced by a unique filename
+       using the mkstemp(3) system call. The default value of this
+       setting is <literal>/tmp/cf.XXXXXX.p</literal>.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </refsect2>
+  <refsect2>
+   <title>log</title>
    <para>
-     The following elements are honored by the ZOOM module of Metaproxy.
-     Note that unknown elements are silently ignored. There are several
-     elements in use that makes no sense to the ZOOM module.
+    The <literal>log</literal> element controls logging for the
+    ZOOM filter.
    </para>
    <variablelist>
-     <varlistentry>
-       <term>authentication</term><listitem>
-        <para>
-          Authentication parameters to be sent to the target. For
-          Z39.50 targets, this will be sent as part of the
-          Init Request.
-        </para>
-        <para>
-          If this value is omitted or empty, not authentication information
-          is simply omitted.
-        </para>
-       </listitem>
-     </varlistentry>
+    <varlistentry>
+     <term>attribute <literal>apdu</literal></term>
+     <listitem>
+      <para>
+       If the value of apdu is "true", then protocol packages
+       (APDUs and HTTP packages) from the ZOOM filter will be
+       logged to the yaz_log system. A value of "false" will
+       not perform logging of protocol packages (the default
+       behavior).
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </refsect2>
+ </refsect1>
+ <refsect1>
+  <title>QUERY HANDLING</title>
+  <para>
+   The ZOOM filter accepts three query types: RPN(Type-1), CCL and
+   CQL.
+  </para>
+  <para>
+   Queries are converted in two separate steps. In the first step
+   the input query is converted to RPN/Type-1. This is always
+   the common internal format between step 1 and step 2.
+   In step 2 the query is converted to the native query type of the target.
+  </para>
+  <para>
+   Step 1: for RPN, the query is passed un-modified to the target.
+  </para>
+  <para>
+   Step 1: for CCL, the query is converted to RPN via
+   <link linkend="cclmap"><literal>cclmap</literal></link> elements part of
+   the target profile as well as 
+   <link linkend="cclmap_base">base CCL maps</link>.
+  </para>
+  <para>
+   Step 1: For CQL, the query is converted to CCL. The mappings of
+   CQL fields to CCL fields are handled by
+   <link linkend="fieldmap"><literal>fieldmap</literal></link>
+   elements as part of the target profile. The resulting query, CCL,
+   is the converted to RPN using the schema mentioned earlier (via
+   <literal>cclmap</literal>).
+  </para>
+  <para>
+   Step 2: If the target is Z39.50-based, it is passed verbatim (RPN).
+   If the target is SRU-based, the RPN will be converted to CQL.
+   If the target is SOLR-based, the RPN will be converted to SOLR's query
+   type.
+  </para>
+ </refsect1>
+ <refsect1>
+  <title>SORTING</title>
+  <para>
+   The ZOOM module actively handle CQL sorting - using the SORTBY parameter
+   which was introduced in SRU version 1.2. The conversion from SORTBY clause
+   to native sort for some target is driven by the two parameters: 
+   <link linkend="sortStrategy"><literal>sortStrategy</literal></link>
+   and <link linkend="sortmap"><literal>sortmap_</literal><replaceable>field</replaceable></link>.
+  </para>
+  <para>
+   If a sort field that does not have an equivalent
+   <literal>sortmap_</literal>-mapping is passed un-modified through the
+   conversion. It doesn't throw a diagnostic.
+  </para>
+ </refsect1>
+ <refsect1>
+  <title>TARGET PROFILE</title>
+  <para>
+   The ZOOM module is driven by a number of settings that specifies how
+   to handle each target.
+   Note that unknown elements are silently <emphasis>ignored</emphasis>.
+  </para>
+  <para>
+   The elements, in alphabetical order, are:
+  </para>
+  <variablelist>
+   <varlistentry>
+    <term>authentication</term><listitem>
+    <para>
+     Authentication parameters to be sent to the target. For
+     Z39.50 targets, this will be sent as part of the
+     Init Request.
+    </para>
+    <para>
+     If this value is omitted or empty no authentication information is sent.
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry id="cclmap">
+    <term>cclmap_<replaceable>field</replaceable></term><listitem>
+    <para>
+     This value specifies CCL field (qualifier) definition for some
+     field. For Z39.50 targets this most likely will specify the
+     mapping to a numeric use attribute + a structure attribute.
+     For SRU targets, the use attribute should be string based, in
+     order to make the RPN to CQL conversion work properly (step 2).
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry>
+    <term>cfAuth</term><listitem>
+    <para>
+     When cfAuth is defined, its value will be used as authentication
+     to backend target and authentication setting will be specified
+     as part of a database. This is like a "proxy" for authentication and
+     is used for Connector Framework based targets.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>piggyback</term><listitem>
-        <para>
-          A value of 1/true is a hint to the ZOOM module that this Z39.50
-          target supports piggyback searches, ie Search Response with
-          records. Any other value (false) will prevent the ZOOM module
-          to make use of piggyback (all records part of Present Response).
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>cfProxy</term><listitem>
+    <para>
+     Specifies HTTP proxy for the target in the form
+     <replaceable>host</replaceable>:<replaceable>port</replaceable>.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>queryEncoding</term><listitem>
-        <para>
-          If this value is defined, all queries will be converted
-          to this encoding. This should be used for all Z39.50 targets that
-          do not use UTF-8 for query terms.
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>cfSubDb</term><listitem>
+    <para>
+     Specifies sub database for a Connector Framework based target.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>udb</term><listitem>
-        <para>
-          This value is required and specifies the unique database for
-          this profile . All target profiles should hold a unique database.
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry id="contentConnector">
+    <term>contentConnector</term><listitem>
+    <para>
+     Specifies a database for content-based proxy'ing.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>cclmap_*</term><listitem>
-        <para>
-          This value specifies CCL field (qualifier) definition for some
-          field. For Z39.50 targets this most likely will specify the
-          mapping to a numeric use attribute + a structure attribute.
-          For SRU targets, the use attribute should be string based, in
-          order to make the RPN to CQL conversion work properly (step 2).
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>elementSet</term><listitem>
+    <para>
+     Specifies the elementSet to be sent to the target if record
+     transform is enabled (not to be confused' with the record_transform
+     module). The record transform is enabled only if the client uses
+     record syntax = XML and a element set determined by
+     the <literal>element_transform</literal> /
+     <literal>element_raw</literal> from the configuration.
+     By default that is the element sets <literal>pz2</literal>
+     and <literal>raw</literal>.
+     If record transform is not enabled, this setting is 
+     not used and the element set specified by the client
+     is passed verbatim.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>elementSet</term><listitem>
-        <para>
-          Specifies the elementSet to be sent to the target if record
-          transform is enabled (not to be confused' with the record_transform
-          module). The record transform is enabled only if the client uses
-          record syntax = XML and a element set determined by
-          the <literal>element_transform</literal> /
-          <literal>element_raw</literal> from the configuration.
-          By default that is the element sets <literal>pz2</literal>
-          and <literal>raw</literal>.
-          If record transform is not enabled, this setting is 
-          not used and the element set specified by the client
-          is passed verbatim.
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>literalTransform</term><listitem>
+    <para>
+     Specifies a XSL stylesheet to be used if record
+     transform is anabled; see description of elementSet.
+     The XSL transform is only used if the element set is set to the
+     value of <literal>element_transform</literal> in the configuration.
+    </para>
+    <para>
+     The value of literalTransform is the XSL - string encoded.
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry>
+    <term>piggyback</term><listitem>
+    <para>
+     A value of 1/true is a hint to the ZOOM module that this Z39.50
+     target supports piggyback searches, ie Search Response with
+     records. Any other value (false) will prevent the ZOOM module
+     to make use of piggyback (all records part of Present Response).
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry>
+    <term>queryEncoding</term><listitem>
+    <para>
+     If this value is defined, all queries will be converted
+     to this encoding. This should be used for all Z39.50 targets that
+     do not use UTF-8 for query terms.
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry>
+    <term>recordEncoding</term><listitem>
+    <para>
+     Specifies the character encoding of records that are returned
+     by the target. This is primarily used for targets were records
+     are not UTF-8 encoded already. This setting is only used
+     if the record transform is enabled (see description of elementSet).
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>recordEncoding</term><listitem>
-        <para>
-          Specifies the character encoding of records that are returned
-          by the target. This is primarily used for targets were records
-          are not UTF-8 encoded already. This setting is only used
-          if the record transform is enabled (see description of elementSet).
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>requestSyntax</term><listitem>
+    <para>
+     Specifies the record syntax to be specified for the target
+     if record transform is enabled; see description of elementSet.
+     If record transform is not enabled, the record syntax of the
+     client is passed verbatim to the target.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>requestSyntax</term><listitem>
-        <para>
-          Specifies the record syntax to be specified for the target
-          if record transform is enabled; see description of elementSet.
-          If record transform is not enabled, the record syntax of the
-          client is passed verbatim to the target.
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry id="sortmap">
+    <term>sortmap_<replaceable>field</replaceable></term><listitem>
+    <para>
+     This value the native field for a target. The form of the value is
+     given by <link linkend="sortStrategy">sortStrategy</link>.
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry id="sortStrategy">
+    <term>sortStrategy</term><listitem>
+    <para>
+     Specifies sort strategy for a target. One of:
+     <literal>z3950</literal>, <literal>type7</literal>,
+     <literal>cql</literal>, <literal>sru11</literal> or
+     <literal>embed</literal>. The <literal>embed</literal> chooses type-7
+     or CQL sortby depending on whether Type-1 or CQL is
+     actually sent to the target.
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry>
+    <term>sru</term><listitem>
+    <para>
+     If this setting is set, it specifies that the target is web service
+     based and must be one of : <literal>get</literal>,
+     <literal>post</literal>, <literal>soap</literal>
+     or <literal>solr</literal>.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>sru</term><listitem>
-        <para>
-          If this setting is set, it specifies that the target is web service
-          based and must be one of : <literal>get</literal>,
-          <literal>post</literal>, <literal>soap</literal>
-          or <literal>solr</literal>.
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>transform</term><listitem>
+    <para>
+     Specifies a XSL stylesheet filename to be used if record
+     transform is anabled; see description of elementSet.
+     The XSL transform is only used if the element set is set to the
+     value of <literal>element_transform</literal> in the configuration.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>transform</term><listitem>
-        <para>
-          Specifies a XSL stylesheet filename to be used if record
-          transform is anabled; see desciprion of elementSet.
-          The XSL transform is only used if the element set is set to the
-          value of <literal>element_transform</literal> in the configuration.
-        </para>
-       </listitem>
-     </varlistentry>
+   <varlistentry>
+    <term>udb</term><listitem>
+    <para>
+     This value is required and specifies the unique database for
+     this profile . All target profiles should hold a unique database.
+    </para>
+   </listitem>
+   </varlistentry>
 
-     <varlistentry>
-       <term>zurl</term><listitem>
-        <para>
-          This is setting is mandatory and specifies the ZURL of the
-          target in the form of host/database. The HTTP method should
-          not be provide as this is guessed from the "sru" attribute value.
-        </para>
-       </listitem>
-     </varlistentry>
-   </variablelist>
+   <varlistentry id="urlRecipe">
+    <term>urlRecipe</term><listitem>
+    <para>
+     The value of this field is a string that generates a dynamic link
+     based on record content. If the resulting string is non-zero in length
+     a new field, <literal>metadata</literal> with attribute 
+     <literal>type="generated-url"</literal>.
+     The contents of this field is the result of the URL recipe conversion.
+     The urlRecipe value may refer to an existing metadata element by
+     ${field[pattern/result/flags]}, which will take content
+     of field and perform a regular expression conversion using the pattern
+     given. For example: <literal>${md-title[\s+/+/g]}</literal> takes
+     metadadata element <literal>title</literal> and converts one or more
+     spaces to a plus character.
+    </para>
+    <para>
+     If the <link linkend="contentConnector">contentConnector</link>
+     setting also defined, the resulting value is
+     augmented with a session string as well as the content proxy server.
+    </para>
+   </listitem>
+   </varlistentry>
+   
+   <varlistentry>
+    <term>zurl</term><listitem>
+    <para>
+     This is setting is mandatory and specifies the ZURL of the
+     target in the form of host/database. The HTTP method should
+     not be provided as this is guessed from the "sru" attribute value.
+    </para>
+   </listitem>
+   </varlistentry>
+  </variablelist>
  </refsect1>
- <refsect1><title>SCHEMA</title>
-   <literallayout><xi:include
-                    xi:href="../xml/schema/filter_zoom.rnc"
-                    xi:parse="text"  
-                    xmlns:xi="http://www.w3.org/2001/XInclude" />
-   </literallayout>
+ <refsect1>
+  <title>SCHEMA</title>
+  <literallayout><xi:include
+  xi:href="../xml/schema/filter_zoom.rnc"
+  xi:parse="text"  
+  xmlns:xi="http://www.w3.org/2001/XInclude" />
+  </literallayout>
  </refsect1>
  
- <refsect1><title>EXAMPLES</title>
+ <refsect1>
+  <title>EXAMPLES</title>
   <para>
    The following configuration illustrates most of the
    facilities:
 ]]>
    </screen>
   </para>
-
+  
  </refsect1> 
  
- <refsect1><title>SEE ALSO</title>
+ <refsect1>
+  <title>SEE ALSO</title>
   <para>
    <citerefentry>
     <refentrytitle>metaproxy</refentrytitle>
 
 <!-- Keep this comment at the end of the file
 Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:1
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-local-catalogs: nil
-sgml-namecase-general:t
+mode: nxml
+nxml-child-indent: 1
 End:
 -->
index 1c64d09..96ed5b8 100644 (file)
@@ -46,6 +46,8 @@
            <sru>get</sru>
            <transform>tmarc.xsl</transform>
            <zurl>localhost:9998/db01</zurl>
+            <sortStrategy>embed</sortStrategy>
+            <sortmap_title>dc.title</sortmap_title>
          </record>
 
           <!-- jstor1 -->
index d9d625c..603f378 100644 (file)
@@ -27,27 +27,15 @@ namespace metaproxy_1 {
 }
 
 namespace std {
-    std::ostream& operator<<(std::ostream& os, metaproxy_1::Origin& o);
+    std::ostream& operator<<(std::ostream& os, const metaproxy_1::Origin& o);
 }
 
 namespace metaproxy_1 {
     
     class Origin {
     public:
-        Origin(std::string listen_host = "", unsigned int listen_port = 0);
+        Origin();
         
-        /// get function - right val in assignment
-        std::string listen_host() const;
-
-        /// set function - left val in assignment
-        std::string & listen_host();
-        /// get function - right val in assignment
-        unsigned int listen_port() const;
-        
-        /// set function - left val in assignment
-        unsigned int & listen_port();
         /// set client IP info - left val in assignment
         void set_tcpip_address(std::string addr, unsigned long id);
 
@@ -59,26 +47,19 @@ namespace metaproxy_1 {
         
         /// get tcpip address
         std::string get_address();
+
+        void set_custom_session(const std::string &s);
     private:
         friend std::ostream& 
-        std::operator<<(std::ostream& os,  metaproxy_1::Origin& o);
+        std::operator<<(std::ostream& os, const metaproxy_1::Origin& o);
         
-        enum origin_t {
-            API,
-            UNIX,
-            TCPIP
-        } m_type;
-        std::string m_address; // UNIX+TCPIP
+        std::string m_address;
         unsigned int m_origin_id;
-        std::string m_listen_host;
-        unsigned int m_listen_port;
         int m_max_sockets;
+        std::string m_custom_session;
     };
-
 }
 
-
-
 #endif
 /*
  * Local variables:
index 8800fa3..735f11d 100644 (file)
@@ -35,7 +35,7 @@ namespace metaproxy_1 {
 
 namespace std 
 {
-    std::ostream& operator<<(std::ostream& os, metaproxy_1::Package& p);
+    std::ostream& operator<<(std::ostream& os, const metaproxy_1::Package& p);
 }
 
 namespace metaproxy_1 {
@@ -63,14 +63,11 @@ namespace metaproxy_1 {
         
         /// get function - right val in assignment
         Origin origin() const;
-        
+       
         /// set function - left val in assignment
         Origin & origin();
         
         /// set function - can be chained
-        Package & origin(const Origin & origin);
-
-        /// set function - can be chained
         Package & router(const Router &router);
 
         yazpp_1::GDU &request();
@@ -79,7 +76,8 @@ namespace metaproxy_1 {
                 
         /// get function - right val in assignment
         Session session() const;
-        
+
+        void log(const char *module, int level, const char *fmt, ...) const;
     private:
         Session m_session;
         Origin m_origin;
index c405877..5723cc9 100644 (file)
@@ -1,6 +1,6 @@
 Summary: Z39.50/SRU router
 Name: metaproxy
-Version: 1.3.9
+Version: 1.3.13
 Release: 1indexdata
 License: GPL
 Group: Applications/Internet
@@ -8,7 +8,7 @@ Vendor: Index Data ApS <info@indexdata.dk>
 Source: metaproxy-%{version}.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
 Prefix: %{_prefix} /etc/metaproxy
-BuildRequires: pkgconfig, libyaz4-devel >= 4.2.8, libyazpp4-devel >= 1.2.7
+BuildRequires: pkgconfig, libyaz4-devel >= 4.2.14, libyazpp4-devel >= 1.2.7
 BuildRequires: libxslt-devel, boost-devel
 Packager: Adam Dickmeiss <adam@indexdata.dk>
 URL: http://www.indexdata.com/metaproxy
index d23dd63..20c39c1 100644 (file)
@@ -25,15 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include <sstream>
 
-//#include "config.hpp"
-//#include "filter.hpp"
-
-//#include <boost/thread/mutex.hpp>
-
-
-
-
-
 namespace mp = metaproxy_1;
 namespace yf = mp::filter;
 
index b7e112f..bc8f39a 100644 (file)
@@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #undef max
 #endif
 
-//#include <iostream>
 #include <list>
 #include <map>
 #include <limits>
index 98d4497..4d4606a 100644 (file)
@@ -104,6 +104,7 @@ namespace metaproxy_1 {
             time_t m_time_last_use;
             mp::Package * m_close_package;
             ~BackendInstance();
+            void timestamp();
         };
         // backends of some class (all with same InitKey)
         class SessionShared::BackendClass : boost::noncopyable {
@@ -331,10 +332,15 @@ yf::SessionShared::BackendClass::get_backend(
 void yf::SessionShared::BackendClass::use_backend(BackendInstancePtr backend)
 {
     backend->m_in_use = true;
-    time(&backend->m_time_last_use);
     backend->m_sequence_this = m_sequence_top++;
 }
 
+void yf::SessionShared::BackendInstance::timestamp()
+{
+    assert(m_in_use);
+    time(&m_time_last_use);
+}
+
 yf::SessionShared::BackendInstance::~BackendInstance()
 {
     delete m_close_package;
@@ -687,6 +693,8 @@ restart:
         else
             result_set_id = "default";
     }
+    found_backend->timestamp();
+
     // we must search ...
     BackendSetPtr new_set(new BackendSet(result_set_id,
                                          databases, query));
@@ -881,6 +889,8 @@ void yf::SessionShared::Frontend::present(mp::Package &package,
         bc->release_backend(found_backend);
         return;
     }
+
+    found_backend->timestamp();
                               
     Z_APDU *p_apdu = zget_APDU(odr, Z_APDU_presentRequest);
     Z_PresentRequest *p_req = p_apdu->u.presentRequest;
@@ -954,6 +964,7 @@ void yf::SessionShared::Frontend::scan(mp::Package &frontend_package,
     else
     {
         Package scan_package(backend->m_session, frontend_package.origin());
+        backend->timestamp();
         scan_package.copy_filter(frontend_package);
         scan_package.request() = apdu_req;
         scan_package.move();
@@ -1015,7 +1026,7 @@ void yf::SessionShared::Rep::expire()
     {
         boost::xtime xt;
         boost::xtime_get(&xt, boost::TIME_UTC);
-        xt.sec += 30;
+        xt.sec += m_session_ttl / 3;
         boost::thread::sleep(xt);
         
         BackendClassMap::const_iterator b_it = m_backend_map.begin();
index 140b346..17e5b55 100644 (file)
@@ -223,6 +223,10 @@ void yf::SRUtoZ3950::Impl::sru(mp::Package &package, Z_GDU *zgdu_req)
         {
             package.origin().set_max_sockets(atoi(arg->value));
         }
+        else if (!strcmp(arg->name, "x-session-id"))
+        {
+            package.origin().set_custom_session(arg->value);
+        }
 
     assert(sru_pdu_req);
 
index 31be152..6c9cabf 100644 (file)
@@ -46,12 +46,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <yaz/log.h>
 #include <yaz/zgdu.h>
 #include <yaz/querytowrbuf.h>
-
-#define ZOOM_SORTBY2 0
-
-#if ZOOM_SORTBY2
 #include <yaz/sortspec.h>
-#endif
+#include <yaz/tokenizer.h>
 
 namespace mp = metaproxy_1;
 namespace yf = mp::filter;
@@ -75,9 +71,11 @@ namespace metaproxy_1 {
             std::string transform_xsl_content;
             std::string urlRecipe;
             std::string contentConnector;
+            std::string sortStrategy;
             bool use_turbomarc;
             bool piggyback;
             CCL_bibset ccl_bibset;
+            std::map<std::string, std::string> sortmap;
             Searchable(CCL_bibset base);
             ~Searchable();
         };
@@ -115,7 +113,8 @@ namespace metaproxy_1 {
             void handle_package(mp::Package &package);
             void handle_search(mp::Package &package);
             void handle_present(mp::Package &package);
-            BackendPtr get_backend_from_databases(std::string &database,
+            BackendPtr get_backend_from_databases(const mp::Package &package,
+                                                  std::string &database,
                                                   int *error,
                                                   char **addinfo,
                                                   ODR odr);
@@ -302,6 +301,7 @@ yf::Zoom::Searchable::Searchable(CCL_bibset base)
 {
     piggyback = true;
     use_turbomarc = true;
+    sortStrategy = "embed";
     ccl_bibset = ccl_qual_dup(base);
 }
 
@@ -476,6 +476,17 @@ yf::Zoom::SearchablePtr yf::Zoom::Impl::parse_torus_record(const xmlNode *ptr)
             ccl_qual_fitem(s->ccl_bibset, value.c_str(),
                            (const char *) ptr->name + 7);
         }
+        else if (!strncmp((const char *) ptr->name,
+                          "sortmap_", 8))
+        {
+            std::string value = mp::xml::get_text(ptr);
+            s->sortmap[(const char *) ptr->name + 8] = value;
+        }
+        else if (!strcmp((const char *) ptr->name,
+                          "sortStrategy"))
+        {
+            s->sortStrategy = mp::xml::get_text(ptr);
+        }
     }
     return s;
 }
@@ -625,6 +636,7 @@ void yf::Zoom::Impl::configure(const xmlNode *ptr, bool test_only,
 }
 
 yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
+    const mp::Package &package,
     std::string &database, int *error, char **addinfo, ODR odr)
 {
     std::list<BackendPtr>::const_iterator map_it;
@@ -648,7 +660,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     it = m_p->s_map.find(torus_db);
     if (it != m_p->s_map.end())
         sptr = it->second;
-    else
+    else if (m_p->torus_url.length() > 0)
     {
         xmlDoc *doc = mp::get_searchable(m_p->torus_url, torus_db, m_p->proxy);
         if (!doc)
@@ -786,17 +798,27 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     const char *param_user = 0;
     const char *param_password = 0;
     const char *param_proxy = 0;
+    char *x_args = 0;  // all x-args to be passed to backend
+    
     if (db_args.length())
     {
+        
         char **names;
         char **values;
-        int i;
         int no_parms = yaz_uri_to_array(db_args.c_str(),
                                         odr, &names, &values);
+        const char **x_names = (const char **)
+            odr_malloc(odr, (1 + no_parms) * sizeof(*x_names));
+        const char **x_values = (const char **)
+            odr_malloc(odr, (1 + no_parms) * sizeof(*x_values));
+        int no_x_names = 0;
+        int i;
         for (i = 0; i < no_parms; i++)
         {
             const char *name = names[i];
             const char *value = values[i];
+            assert(name);
+            assert(value);
             if (!strcmp(name, "user"))
                 param_user = value;
             else if (!strcmp(name, "password"))
@@ -805,6 +827,12 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
                 param_proxy = value;
             else if (!strcmp(name, "cproxysession"))
                 ;
+            else if (name[0] == 'x' && name[1] == '-')
+            {
+                x_names[no_x_names] = name;
+                x_values[no_x_names] = value;
+                no_x_names++;
+            }
             else
             {
                 BackendPtr notfound;
@@ -815,6 +843,12 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
                 return notfound;
             }
         }
+        if (no_x_names)
+        {
+            x_names[no_x_names] = 0; // terminate list
+            yaz_array_to_uri(&x_args, odr, (char **) x_names,
+                             (char **) x_values);
+        }
         if (param_user)
         {
             authentication = std::string(param_user);
@@ -862,7 +896,9 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     }
     else
     {
-        db_args.clear(); // no arguments to be passed (non-CF)
+        db_args.clear(); // Only x-args to be passed (non-CF)
+        if (x_args)
+            db_args = x_args;
 
         size_t found = authentication.find('/');
         
@@ -894,7 +930,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
         FILE *file = fopen(fname, "w");
         if (!file)
         {
-            yaz_log(YLOG_WARN|YLOG_ERRNO, "create %s", fname);
+            package.log("zoom", YLOG_WARN|YLOG_ERRNO, "create %s", fname);
             *error = YAZ_BIB1_TEMPORARY_SYSTEM_ERROR;
             *addinfo = (char *)  odr_malloc(odr, 40 + strlen(fname));
             sprintf(*addinfo, "Could not create %s", fname);
@@ -915,7 +951,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
 
         fwrite(wrbuf_buf(w), 1, wrbuf_len(w), file);
         fclose(file);
-        yaz_log(YLOG_LOG, "file %s created\n", fname);
+        package.log("zoom", YLOG_LOG, "file %s created\n", fname);
         xfree(fname);
     }
 
@@ -931,7 +967,7 @@ yf::Zoom::BackendPtr yf::Zoom::Frontend::get_backend_from_databases(
     }
     if (db_args.length())
         url += "," + db_args;
-    yaz_log(YLOG_LOG, "url=%s", url.c_str());
+    package.log("zoom", YLOG_LOG, "url=%s", url.c_str());
     b->connect(url, error, addinfo, odr);
     if (*error == 0)
     {
@@ -1250,115 +1286,6 @@ struct cql_node *yf::Zoom::Impl::convert_cql_fields(struct cql_node *cn,
     return r;
 }
 
-
-#if !ZOOM_SORTBY2
-static void sort_pqf_type_7(WRBUF pqf_wrbuf, const char *sru_sortkeys)
-{
-    /* sortkey layour: path,schema,ascending,caseSensitive,missingValue */
-    /* see cql_sortby_to_sortkeys of YAZ. */
-    char **sortspec;
-    int num_sortspec = 0;
-    int i;
-    NMEM nmem = nmem_create();
-    
-    if (sru_sortkeys)
-        nmem_strsplit_blank(nmem, sru_sortkeys, &sortspec, &num_sortspec);
-    if (num_sortspec > 0)
-    {
-        WRBUF w = wrbuf_alloc();
-        for (i = 0; i < num_sortspec; i++)
-        {
-            char **arg;
-            int num_arg;
-            int ascending = 1;
-            nmem_strsplitx(nmem, ",", sortspec[i], &arg, &num_arg, 0);
-            
-            if (num_arg > 2 && arg[2][0])
-                ascending = atoi(arg[2]);
-            
-            wrbuf_puts(w, "@or @attr 1=");
-            yaz_encode_pqf_term(w, arg[0], strlen(arg[0]));
-            wrbuf_printf(w, "@attr 7=%d %d ", ascending ? 1 : 2, i);
-        }
-        if (wrbuf_len(w))
-        {
-            wrbuf_puts(w, wrbuf_cstr(pqf_wrbuf));
-            wrbuf_rewind(pqf_wrbuf);
-            wrbuf_puts(pqf_wrbuf, wrbuf_cstr(w));
-        }
-        wrbuf_destroy(w);
-    }
-    nmem_destroy(nmem);
-}
-#endif
-
-#if !ZOOM_SORTBY2
-static void sort_via_cql(WRBUF cql_sortby, const char *sru_sortkeys)
-{
-    /* sortkey layour: path,schema,ascending,caseSensitive,missingValue */
-    /* see cql_sortby_to_sortkeys of YAZ. */
-    char **sortspec;
-    int num_sortspec = 0;
-    int i;
-    NMEM nmem = nmem_create();
-    
-    if (sru_sortkeys)
-        nmem_strsplit_blank(nmem, sru_sortkeys, &sortspec, &num_sortspec);
-    if (num_sortspec > 0)
-    {
-        WRBUF w = wrbuf_alloc();
-        for (i = 0; i < num_sortspec; i++)
-        {
-            char **arg;
-            int num_arg;
-            int ascending = 1;
-            int case_sensitive = 0;
-            const char *missing = 0;
-            nmem_strsplitx(nmem, ",", sortspec[i], &arg, &num_arg, 0);
-            
-            if (num_arg > 2 && arg[2][0])
-                ascending = atoi(arg[2]);
-            if (num_arg > 3 && arg[3][0])
-                case_sensitive = atoi(arg[3]);
-            if (num_arg > 4 && arg[4][0])
-                missing = arg[4];
-            if (i > 0)
-                wrbuf_puts(w, " ");
-            else
-                wrbuf_puts(w, " sortby ");
-            wrbuf_puts(w, arg[0]);  /* field */
-            wrbuf_puts(w, "/");
-            wrbuf_puts(w, ascending ? "ascending" : "descending");
-            if (case_sensitive)
-                wrbuf_puts(w, "/respectCase");
-            if (missing)
-            {
-                if (!strcmp(missing, "omit"))
-                    wrbuf_puts(w, "/missingOmit");
-                else if (!strcmp(missing, "abort"))
-                    wrbuf_puts(w, "/missingFail");
-                else if (!strcmp(missing, "lowValue"))
-                    wrbuf_puts(w, "/missingLow");
-                else if (!strcmp(missing, "highValue"))
-                    wrbuf_puts(w, "/missingHigh");
-            }
-        }
-        if (wrbuf_len(w))
-            wrbuf_puts(cql_sortby, wrbuf_cstr(w));
-        wrbuf_destroy(w);
-    }
-    nmem_destroy(nmem);
-}
-#endif
-
-#if YAZ_VERSIONL < 0x40206
-static void wrbuf_vp_puts(const char *buf, void *client_data)
-{
-    WRBUF b = (WRBUF) client_data;
-    wrbuf_puts(b, buf);
-}
-#endif
-
 void yf::Zoom::Frontend::handle_search(mp::Package &package)
 {
     Z_GDU *gdu = package.request().get();
@@ -1377,7 +1304,8 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
     int error = 0;
     char *addinfo = 0;
     std::string db(sr->databaseNames[0]);
-    BackendPtr b = get_backend_from_databases(db, &error, &addinfo, odr);
+    BackendPtr b = get_backend_from_databases(package, db, &error,
+                                              &addinfo, odr);
     if (error)
     {
         apdu_res = 
@@ -1459,16 +1387,44 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
             WRBUF sru_sortkeys_wrbuf = wrbuf_alloc();
 
             cql_sortby_to_sortkeys(cn, wrbuf_vp_puts, sru_sortkeys_wrbuf);
-#if ZOOM_SORTBY2
             WRBUF sort_spec_wrbuf = wrbuf_alloc();
             yaz_srw_sortkeys_to_sort_spec(wrbuf_cstr(sru_sortkeys_wrbuf),
                                           sort_spec_wrbuf);
-            sortkeys.assign(wrbuf_cstr(sort_spec_wrbuf));
-            wrbuf_destroy(sort_spec_wrbuf);
-#else
-            sortkeys.assign(wrbuf_cstr(sru_sortkeys_wrbuf));
-#endif
             wrbuf_destroy(sru_sortkeys_wrbuf);
+
+            yaz_tok_cfg_t tc = yaz_tok_cfg_create();
+            yaz_tok_parse_t tp =
+                yaz_tok_parse_buf(tc, wrbuf_cstr(sort_spec_wrbuf));
+            yaz_tok_cfg_destroy(tc);
+
+            /* go through sortspec and map fields */
+            int token = yaz_tok_move(tp);
+            while (token != YAZ_TOK_EOF)
+            {
+                if (token == YAZ_TOK_STRING)
+                {
+                    const char *field = yaz_tok_parse_string(tp);
+                    std::map<std::string,std::string>::iterator it;
+                    it = b->sptr->sortmap.find(field);
+                    if (it != b->sptr->sortmap.end())
+                        sortkeys += it->second;
+                    else
+                        sortkeys += field;
+                }
+                sortkeys += " ";
+                token = yaz_tok_move(tp);
+                if (token == YAZ_TOK_STRING)
+                {
+                    sortkeys += yaz_tok_parse_string(tp);
+                }
+                if (token != YAZ_TOK_EOF)
+                {
+                    sortkeys += " ";
+                    token = yaz_tok_move(tp);
+                }
+            }
+            yaz_tok_parse_destroy(tp);
+            wrbuf_destroy(sort_spec_wrbuf);
         }
         cql_parser_destroy(cp);
         if (r)
@@ -1495,7 +1451,7 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
         assert(pqf_wrbuf == 0);
         int cerror, cpos;
         struct ccl_rpn_node *cn;
-        yaz_log(YLOG_LOG, "CCL: %s", wrbuf_cstr(ccl_wrbuf));
+        package.log("zoom", YLOG_LOG, "CCL: %s", wrbuf_cstr(ccl_wrbuf));
         cn = ccl_find_str(b->sptr->ccl_bibset, wrbuf_cstr(ccl_wrbuf),
                           &cerror, &cpos);
         wrbuf_destroy(ccl_wrbuf);
@@ -1522,16 +1478,14 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
         }
         pqf_wrbuf = wrbuf_alloc();
         ccl_pquery(pqf_wrbuf, cn);
-        yaz_log(YLOG_LOG, "RPN: %s", wrbuf_cstr(pqf_wrbuf));
+        package.log("zoom", YLOG_LOG, "RPN: %s", wrbuf_cstr(pqf_wrbuf));
         ccl_rpn_delete(cn);
     }
     
     assert(pqf_wrbuf);
 
     ZOOM_query q = ZOOM_query_create();
-#if ZOOM_SORTBY2
-    ZOOM_query_sortby2(q, "embed", sortkeys.c_str());
-#endif
+    ZOOM_query_sortby2(q, b->sptr->sortStrategy.c_str(), sortkeys.c_str());
 
     if (b->get_option("sru"))
     {
@@ -1555,15 +1509,11 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
             status = cql_transform_rpn2cql_wrbuf(cqlt, wrb, zquery);
             
             cql_transform_close(cqlt);
-#if !ZOOM_SORTBY2
-            if (status == 0)
-                sort_via_cql(wrb, sortkeys.c_str());
-#endif
         }
         if (status == 0)
         {
             ZOOM_query_cql(q, wrbuf_cstr(wrb));
-            yaz_log(YLOG_LOG, "CQL: %s", wrbuf_cstr(wrb));
+            package.log("zoom", YLOG_LOG, "CQL: %s", wrbuf_cstr(wrb));
             b->search(q, &hits, &error, &addinfo, odr);
         }
         ZOOM_query_destroy(q);
@@ -1581,11 +1531,8 @@ void yf::Zoom::Frontend::handle_search(mp::Package &package)
     }
     else
     {
-#if !ZOOM_SORTBY2
-        sort_pqf_type_7(pqf_wrbuf, sortkeys.c_str());
-#endif
         ZOOM_query_prefix(q, wrbuf_cstr(pqf_wrbuf));
-        yaz_log(YLOG_LOG, "search PQF: %s", wrbuf_cstr(pqf_wrbuf));
+        package.log("zoom", YLOG_LOG, "search PQF: %s", wrbuf_cstr(pqf_wrbuf));
         b->search(q, &hits, &error, &addinfo, odr);
         ZOOM_query_destroy(q);
         wrbuf_destroy(pqf_wrbuf);
index 500a446..498629c 100644 (file)
@@ -23,33 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 namespace mp = metaproxy_1;
 
-mp::Origin::Origin(std::string listen_host, 
-                   unsigned int listen_port) 
-    : m_type(API), m_address(""), m_origin_id(0),
-      m_listen_host(listen_host), m_listen_port(listen_port), m_max_sockets(0)
+mp::Origin::Origin() : m_address(""), m_origin_id(0), m_max_sockets(0)
 {
 }
 
-std::string mp::Origin::listen_host() const
-{
-    return m_listen_host;
-};
-
-std::string & mp::Origin::listen_host()
-{
-    return m_listen_host;
-};
-
-unsigned int mp::Origin::listen_port() const
-{
-    return m_listen_port;
-};
-
-unsigned int & mp::Origin::listen_port()
-{
-    return m_listen_port;
-};
-
 void mp::Origin::set_max_sockets(int max_sockets)
 {
     m_max_sockets = max_sockets;
@@ -62,23 +39,29 @@ int mp::Origin::get_max_sockets()
 
 void mp::Origin::set_tcpip_address(std::string addr, unsigned long s)
 {
-    m_type = TCPIP;
     m_address = addr;
     m_origin_id = s;
 }
 
+void mp::Origin::set_custom_session(const std::string &s)
+{
+    m_custom_session = s;
+}
+
 std::string mp::Origin::get_address()
 {
     return m_address;
 }
 
-std::ostream& std::operator<<(std::ostream& os,  mp::Origin& o)
+std::ostream& std::operator<<(std::ostream& os, const mp::Origin& o)
 {
-    if (o.m_address != "")
+    if (o.m_address.length())
         os << o.m_address;
     else
         os << "0";
     os << ":" << o.m_origin_id;
+    if (o.m_custom_session.length())
+        os << ":" << o.m_custom_session;
     return os;
 }
                 
index df45faf..23c745a 100644 (file)
@@ -18,8 +18,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "config.hpp"
 #include <metaproxy/package.hpp>
+#include <yaz/snprintf.h>
+#include <yaz/log.h>
 
-#include <iostream>
+#include <sstream>
 
 namespace mp = metaproxy_1;
 
@@ -79,18 +81,12 @@ mp::Origin mp::Package::origin() const
 {
     return m_origin;
 }
-        
+    
 mp::Origin & mp::Package::origin()
 {
     return m_origin;
 }
 
-mp::Package & mp::Package::origin(const Origin & origin)
-{
-    m_origin = origin;
-    return *this;
-}
-
 mp::Package & mp::Package::router(const mp::Router &router)
 {
     m_route_pos = router.createpos();
@@ -113,13 +109,28 @@ mp::Session mp::Package::session() const
     return m_session;
 }
 
-std::ostream& std::operator<<(std::ostream& os,  mp::Package& p)
+std::ostream& std::operator<<(std::ostream& os, const mp::Package& p)
 {
     os << p.origin() << " ";
     os << p.session().id();
     return os;
 }
 
+void mp::Package::log(const char *module, int level, const char *fmt, ...) const
+{
+    char buf[4096];
+    va_list ap;
+    va_start(ap, fmt);
+
+    yaz_vsnprintf(buf, sizeof(buf)-30, fmt, ap);
+
+    std::ostringstream os;
+
+    os << module << " " << *this << " " << buf;
+
+    va_end(ap);
+    yaz_log(level, "%s", os.str().c_str());
+}
                 
 /*
  * Local variables:
index 6fb36e7..a904d6e 100644 (file)
@@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "config.hpp"
 #include <metaproxy/xmlutil.hpp>
+#include <string.h>
 #include "router_flexml.hpp"
 #include "factory_filter.hpp"
 #include "factory_static.hpp"
@@ -70,6 +71,7 @@ namespace metaproxy_1 {
                                bool test_only, const char *file_include_path);
         void parse_xml_routes(xmlDocPtr doc, const xmlNode *node,
                               bool test_only, const char *file_include_path);
+        void check_routes_in_filters(const xmlNode *n);
 
         bool m_xinclude;
     private:
@@ -95,7 +97,7 @@ void mp::RouterFleXML::Rep::parse_xml_filters(xmlDocPtr doc,
                                               const char *file_include_path)
 {
     unsigned int filter_nr = 0;
-    while(node && mp::xml::check_element_mp(node, "filter"))
+    while (node && mp::xml::check_element_mp(node, "filter"))
     {
         filter_nr++;
 
@@ -147,7 +149,7 @@ void mp::RouterFleXML::Rep::parse_xml_routes(xmlDocPtr doc,
     mp::xml::check_element_mp(node, "route");
 
     unsigned int route_nr = 0;
-    while(mp::xml::is_element_mp(node, "route"))
+    while (mp::xml::is_element_mp(node, "route"))
     {
         route_nr++;
 
@@ -175,7 +177,7 @@ void mp::RouterFleXML::Rep::parse_xml_routes(xmlDocPtr doc,
         const xmlNode* node3 = mp::xml::jump_to_children(node, XML_ELEMENT_NODE);
 
         unsigned int filter3_nr = 0;
-        while(node3 && mp::xml::check_element_mp(node3, "filter"))
+        while (node3 && mp::xml::check_element_mp(node3, "filter"))
         {
             filter3_nr++;
             
@@ -239,6 +241,43 @@ void mp::RouterFleXML::Rep::parse_xml_routes(xmlDocPtr doc,
     }
 }
 
+void mp::RouterFleXML::Rep::check_routes_in_filters(const xmlNode *node)
+{
+    while (node)
+    {
+        if (mp::xml::is_element_mp(node, "filter"))
+        {
+            const xmlNode *n =
+                mp::xml::jump_to_children(node, XML_ELEMENT_NODE);
+            while (n)
+            {
+                const struct _xmlAttr *attr;
+                // we assume thar that route attribute is only at one level
+                // below filter.. At least that works for multi and virt_db.
+                for (attr = n->properties; attr; attr = attr->next)
+                {
+                    if (!strcmp((const char *) attr->name, "route"))
+                    {
+                        std::string value;
+                        
+                        if (attr->children && attr->children->type == XML_TEXT_NODE)
+                            value = std::string((const char *)attr->children->content);
+       
+                        std::map<std::string,RouterFleXML::Route>::iterator it;
+                        it = m_routes.find(value);
+                        if (it == m_routes.end())
+                        {
+                            throw mp::XMLError("Route '" + value + "' does not exist");
+                        }
+                    }
+                }
+                n = mp::xml::jump_to_next(n, XML_ELEMENT_NODE);
+            }
+        }
+        node = mp::xml::jump_to_next(node, XML_ELEMENT_NODE);
+    }
+}
+
 void mp::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc,
                                                  bool test_only,
                                                  const char *file_include_path)
@@ -268,7 +307,6 @@ void mp::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc,
     if (mp::xml::check_element_mp(node, "start"))
     {
         const struct _xmlAttr *attr;
-        std::string id_value;
         for (attr = node->properties; attr; attr = attr->next)
         {
             std::string name = std::string((const char *) attr->name);
@@ -280,7 +318,7 @@ void mp::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc,
             if (name == "route")
                 m_start_route = value;
             else
-                throw mp::XMLError("Only attribute start allowed"
+                throw mp::XMLError("Only attribute route allowed"
                                     " in element 'start'. Got " + name);
         }
         node = mp::xml::jump_to_next(node, XML_ELEMENT_NODE);
@@ -306,7 +344,32 @@ void mp::RouterFleXML::Rep::parse_xml_config_dom(xmlDocPtr doc,
         throw mp::XMLError("Unexpected element " 
                             + std::string((const char *)node->name));
     }
-}        
+
+    node = mp::xml::jump_to_children(root, XML_ELEMENT_NODE);
+    while (node)
+    {
+        if (mp::xml::is_element_mp(node, "filters"))
+            check_routes_in_filters(
+                mp::xml::jump_to_children(node,
+                                          XML_ELEMENT_NODE));
+        else if (mp::xml::is_element_mp(node, "routes"))
+        {
+            const xmlNode* n = mp::xml::jump_to_children(node,
+                                                         XML_ELEMENT_NODE);
+            while (n)
+            {
+                if (mp::xml::is_element_mp(n, "route"))
+                {
+                    check_routes_in_filters(
+                        mp::xml::jump_to_children(n, XML_ELEMENT_NODE));
+                    
+                }
+                n = mp::xml::jump_to_next(n, XML_ELEMENT_NODE);
+            }
+        }
+        node = mp::xml::jump_to_next(node, XML_ELEMENT_NODE);
+    }
+}
 
 mp::RouterFleXML::Rep::Rep() : m_xinclude(false)
 {
index a9b3d66..213b271 100644 (file)
@@ -49,8 +49,8 @@ mp_util::SRUServerInfo mp_util::get_sru_server_info(mp::Package &package)
     mp_util::SRUServerInfo sruinfo;
 
     // getting host and port info
-    sruinfo.host = package.origin().listen_host();
-    sruinfo.port = mp_util::to_string(package.origin().listen_port());
+    sruinfo.host = "localhost";
+    sruinfo.port = "80";
 
     // overwriting host and port info if set from HTTP Host header
     Z_GDU *zgdu_req = package.request().get();
index e715614..f3661f9 100644 (file)
@@ -53,7 +53,8 @@ xmlDoc *mp::get_searchable(std::string url_template, const std::string &db,
                                                   0, /* content buf */
                                                   0  /* content_len */
         );
-    if (http_response->code == 200 && http_response->content_buf)
+    if (http_response && http_response->code == 200 && 
+        http_response->content_buf)
         doc = xmlParseMemory(http_response->content_buf,
                              http_response->content_len);
     yaz_url_destroy(url_p);
index f792e02..1f335a1 100644 (file)
@@ -693,7 +693,6 @@ std::string mp_util::uri_encode(std::string s)
     return result;
 }
 
-
 /*
  * Local variables:
  * c-basic-offset: 4
index 37daeb3..6961cb9 100644 (file)
@@ -7,7 +7,7 @@
 DEBUG=0   # 0 for release, 1 for debug
 
 # Metaproxy version
-VERSION=1.3.9
+VERSION=1.3.13
 
 # YAZ and YAZ++ directories
 YAZ_DIR=..\..\yaz
index f9e682b..144efd1 100644 (file)
@@ -35,7 +35,11 @@ filter_zoom =
         element mp:cfAuth { xsd:string }?,
         element mp:cfProxy { xsd:string }?,
         element mp:cfSubDb { xsd:string }?,
-        element mp:contentConnector { xsd:string }?
+        element mp:contentConnector { xsd:string }?,
+        element mp:sortStrategy { xsd:string }?,
+        element mp:sortmap_author { xsd:string }?,
+        element mp:sortmap_date { xsd:string }?,
+        element mp:sortmap_title { xsd:string }?
       }*
     }?
   }?,