added documentation on zeerex_explain filter
[metaproxy-moved-to-github.git] / doc / book.xml
index 20ac360..a191019 100644 (file)
      -->
      <!NOTATION PDF SYSTEM "PDF">
 ]>
-<!-- $Id: book.xml,v 1.35 2006-06-21 15:08:58 mike Exp $ -->
+<!-- $Id: book.xml,v 1.46 2007-01-05 10:56:17 marc Exp $ -->
 <book id="metaproxy">
  <bookinfo>
   <title>Metaproxy - User's Guide and Reference</title>
   <author>
-   <firstname>Mike</firstname><surname>Taylor</surname>
+   <firstname>Adam</firstname><surname>Dickmeiss</surname>
   </author>
   <author>
-   <firstname>Adam</firstname><surname>Dickmeiss</surname>
+   <firstname>Marc</firstname><surname>Cromme</surname>
+  </author>
+  <author>
+   <firstname>Mike</firstname><surname>Taylor</surname>
   </author>
   <copyright>
-   <year>2006</year>
+   <year>2005-2007</year>
    <holder>Index Data ApS</holder>
   </copyright>
   <abstract>
@@ -76,7 +79,7 @@
   
   <para>
    <ulink url="&url.metaproxy;">Metaproxy</ulink>
-   is a standalone program that acts as a universal router, proxy and
+   is a stand alone program that acts as a universal router, proxy and
    encapsulated metasearcher for information retrieval protocols such
    as <ulink url="&url.z39.50;">Z39.50</ulink>, and in the future
    <ulink url="&url.sru;">SRU</ulink> and <ulink url="&url.srw;">SRW</ulink>.
    being more powerful, flexible, configurable and extensible.  Among
    its many advantages over the older, more pedestrian work are
    support for multiplexing (encapsulated metasearching), routing by
-   database name, authentication and authorisation and serving local
+   database name, authentication and authorization and serving local
    files via HTTP.  Equally significant, its modular architecture
    facilitites the creation of pluggable modules implementing further
    functionality.
      You may modify your copy of the software (fix bugs, add features)
      if you need to.  We encourage you to send your changes back to us for
      integration into the master copy, but you are not obliged to do so.  You
-      may NOT pass your changes on to any other party.
+     may NOT pass your changes on to any other party.
     </para>
    </listitem>
    <listitem>
    for more information.
   </para>
   <para>
-   We have succesfully built Metaproxy using the compilers
+   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.
   </para>
      <literal>\boost\lib</literal>, <literal>\boost\include</literal>.
     </para>
     <para>
-     For more informatation about installing Boost refer to the
+     For more information about installing Boost refer to the
      <ulink url="&url.boost.getting.started;">getting started</ulink>
      pages.
     </para>
      <ulink url="&url.libxml2.download.win32;">here</ulink>.
     </para>
     <para>
-     Libxslt has other dependencies, but thes can all be downloaded
+     Libxslt has other dependencies, but these can all be downloaded
      from the same site. Get the following:
      iconv, zlib, libxml2, libxslt.
     </para>
    <section id="installation.windows.metaproxy">
     <title>Metaproxy</title>
     <para>
-     Metaproxy is shipped with NMAKE makfiles as well - similar
+     Metaproxy is shipped with NMAKE makefiles as well - similar
      to those found in the YAZ++/YAZ packages. Adjust this Makefile
      to point to the proper locations of Boost, Libxslt, Libxml2,
      zlib, iconv, yaz and yazpp.
     </variablelist>
     
     <para>
-     After succesful compilation you'll find
+     After successful compilation you'll find
      <literal>metaproxy.exe</literal> in the
      <literal>bin</literal> directory.
     </para>
      <para>
       In general, packages are doctored as they pass through
       Metaproxy.  For example, when the proxy performs authentication
-      and authorisation on a Z39.50 Init request, it removes the
+      and authorization on a Z39.50 Init request, it removes the
       authentication credentials from the package so that they are not
       passed onto the back-end server; and when search-response
       packages are obtained from multiple servers, they are merged
       The word ``filter'' is sometimes used rather loosely, in two
       different ways: it may be used to mean a particular
       <emphasis>type</emphasis> of filter, as when we speak of ``the
-      auth_simplefilter'' or ``the multi filter''; or it may be used
+      auth_simple filter'' or ``the multi filter''; or it may be used
       to be a specific <emphasis>instance</emphasis> of a filter
       within a Metaproxy configuration.  For example, a single
       configuration will often contain multiple instances of the
     as part of Metaproxy, and others may be provided by third parties
     and dynamically loaded.  They all conform to the same simple API
     of essentially two methods: <function>configure()</function> is
-    called at startup time, and is passed a DOM tree representing that
+    called at startup time, and is passed an XML DOM tree representing that
     part of the configuration file that pertains to this filter
     instance: it is expected to walk that tree extracting relevant
     information; and <function>process()</function> is called every
     packages
     (<literal>frontend_net</literal>);
     others are sinks: they consume packages and return a result
-    (<literal>z3950_client</literal>,
-    <literal>backend_test</literal>,
-    <literal>http_file</literal>);
+    (<literal>backend_test</literal>,
+    <literal>bounce</literal>,
+    <literal>http_file</literal>, 
+    <literal>z3950_client</literal>);
     the others are true filters, that read, process and pass on the
     packages they are fed
     (<literal>auth_simple</literal>,
     <literal>log</literal>,
     <literal>multi</literal>,
     <literal>query_rewrite</literal>,
+    <literal>record_transform</literal>,
     <literal>session_shared</literal>,
+    <literal>sru_z3950</literal>,
     <literal>template</literal>,
     <literal>virt_db</literal>).
    </para>
    <para>
     We now briefly consider each of the types of filter supported by
     the core Metaproxy binary.  This overview is intended to give a
-    flavour of the available functionality; more detailed information
+    flavor of the available functionality; more detailed information
     about each type of filter is included below in
     <link linkend="filterref"
          >the reference guide to Metaproxy filters</link>.
     The filters are here listed in alphabetical order:
    </para>
    
+<!--
+
+### New filters:
+
+New virt_db-alike that does inteligent peer choice, explain merging,
+adds FD&N to explain.  Keeps init responses (like "virt_db Classic"),
+makes routing choices based on local explain knowledge.  Ref IDDI
+paper.
+
+Filter to convert Explain Classic to ZeeRex.
+
+CQL2PQF (which needs augmented ZeeRex) - MARC for Talis.
+
+SRU2Z39.50 (ditto).
+
+Figure out what additional information we need in:
+       ZeeRex (check against D3.1)
+       Init request (e.g. loop detection)
+       Query package (e.g. number of hops)
+       Query response (e.g. record source)
+
+-->
+
    <section>
     <title><literal>auth_simple</literal>
      (mp::filter::AuthSimple)</title>
     <para>
-     Simple authentication and authorisation.  The configuration
+     Simple authentication and authorization.  The configuration
      specifies the name of a file that is the user register, which
      lists <varname>username</varname>:<varname>password</varname>
      pairs, one per line, colon separated. When a session begins, it
     <title><literal>backend_test</literal>
     (mp::filter::Backend_test)</title>
     <para>
-     A sink that provides dummy responses in the manner of the
+     A partial sink that provides dummy responses in the manner of the
      <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
      for testing.  Seriously, you don't need this.  Pretend you didn't
      even read this section.
    </section>
    
    <section>
+    <title><literal>bounce</literal>
+    (mp::filter::Bounce)</title>
+    <para>
+     A sink that swallows <emphasis>all packages</emphasis>, 
+     and returns them almost unprocessed.
+     It never sends any package of any type further down the row, but
+     sets Z39.50 packages to Z_Close, and HTTP_Request packages to
+     HTTP_Response err code 400 packages, and adds a suitable bounce
+     message. 
+     The bounce filter is usually added at end of each filter chain
+     config.xml to prevent infinite hanging of for example HTTP
+     requests packages when only the Z39.50 client partial sink 
+     filter is found in the
+     route.  
+    </para>
+   </section>
+   
+   <section>
     <title><literal>frontend_net</literal>
      (mp::filter::FrontendNet)</title>
     <para>
      A source that accepts Z39.50 connections from a port
      specified in the configuration, reads protocol units, and
      feeds them into the next filter in the route.  When the result is
-     revceived, it is returned to the original origin.
+     received, it is returned to the original origin.
     </para>
    </section>
 
     <title><literal>http_file</literal>
      (mp::filter::HttpFile)</title>
     <para>
-     A sink that returns the contents of files from the local
-     filesystem in response to HTTP requests.  (Yes, Virginia, this
+     A partial sink which swallows only HTTP_Request packages, and 
+     returns the contents of files from the local
+     filesystem in response to HTTP requests.  
+     It lets Z39.50 packages and all other forthcoming package types
+     pass untouched. 
+     (Yes, Virginia, this
      does mean that Metaproxy is also a Web-server in its spare time.  So
      far it does not contain either an email-reader or a Lisp
      interpreter, but that day is surely coming.)
    </section>
    
    <section>
+    <title><literal>load_balance</literal>
+     (mp::filter::LoadBalance)</title>
+    <para>
+     Performs load balancing for incoming Z39.50 init requests.
+     It is used together with the <literal>virt_db</literal> filter,
+     but unlike the <literal>multi</literal> filter it does send an
+     entire session to only one of the virtual backends. The 
+     <literal>load_balance</literal> filter is assuming that
+     all backend targets have equal content, and chooses the backend
+     with least load cost for a new session.
+   </para>
+   </section>
+      
+   <section>
     <title><literal>log</literal>
      (mp::filter::Log)</title>
     <para>
      Writes logging information to standard output, and passes on
-     the package unchanged.
+     the package unchanged. A log file name can be specified, as well
+     as multiple different logging formats.
    </para>
    </section>
-   
+
    <section>
    <title><literal>multi</literal>
      (mp::filter::Multi)</title>
     </para>
    </section>
    
+   
+   <section>
+    <title><literal>record_transform</literal>
+    (mp::filter::RecordTransform)</title>
+    <para>
+     This filter acts only on Z3950 present requests, and let all
+     other types of packages and requests pass untouched. It's use is
+     twofold: blocking Z3950  present requests, which the backend
+     server does not understand and can not honor, and transforming
+     the present syntax and elementset name according to the rules
+     specified, to fetch only existing record formats, and transform
+     them on the fly to requested record syntaxes.
+    </para>
+   </section>
+
    <section>
     <title><literal>session_shared</literal>
      (mp::filter::SessionShared)</title>
      </para>
     </warning>
    </section>
+
+   <section>
+    <title><literal>sru_z3950</literal>
+    (mp::filter::SRUtoZ3950)</title>
+    <para>
+     This filter transforms valid
+     SRU GET/POST/SOAP searchRetrieve requests to Z3950 init, search,
+     and present requests, and wraps the
+     received hit counts and XML records into suitable SRU response
+     messages.
+     The <literal>sru_z3950</literal> filter does only process SRU
+     GET/POST/SOAP explain requests in a very crude fashion, returning
+     the absolute minimum required by the standard. Full ZeeReX
+     explain support is added by including the  
+     <literal>zeerex_explain</literal> filter before the 
+     <literal>sru_z3950</literal> filter.
+    </para>
+   </section>
    
    <section>
     <title><literal>template</literal>
    
    <section>
     <title><literal>virt_db</literal>
-     (mp::filter::Virt_db)</title>
+     (mp::filter::VirtualDB)</title>
     <para>
      Performs virtual database selection: based on the name of the
      database in the search request, a server is selected, and its
     <title><literal>z3950_client</literal>
      (mp::filter::Z3950Client)</title>
     <para>
-     Performs Z39.50 searching and retrieval by proxying the
+     A partial sink which swallows only Z39.50 packages.
+     It performs Z39.50 searching and retrieval by proxying the
      packages that are passed to it.  Init requests are sent to the
      address specified in the <literal>VAL_PROXY</literal> otherInfo
      attached to the request: this may have been specified by client,
      or generated by a <literal>virt_db</literal> filter earlier in
      the route.  Subsequent requests are sent to the same address,
      which is remembered at Init time in a Session object.
+     HTTP_Request packages and all other forthcoming package types
+     are passed untouched. 
     </para>
   </section>
+
+
+   <section>
+    <title><literal>zeerex_explain</literal>
+     (mp::filter::ZeerexExplain)</title>
+    <para>
+     This filter acts as a sink for
+     SRU GET/POST/SOAP explain requests, returning a static ZeeReX
+     Explain XML record from the config section. All other packages
+     are passed through, including SRU GET/POST/SOAP searchRetrieve
+     requests, which are handled by a following
+     <literal>sru_z3950</literal> filter.
+     See the 
+     <ulink url="&url.zeerex.explain;">ZeeReX Explain</ulink>
+     standard pages and the 
+     <ulink url="&url.sru.explain;">SRU Explain</ulink> pages
+     for more information on the correct explain syntax.
+    </para>
+   </section>
+   
+
   </section>
   
   
      </listitem>
     </varlistentry>
     <varlistentry>
-     <term><literal>frontend_sru</literal> (source)</term>
-     <listitem>
-      <para>
-       Receive SRU (and perhaps SRW) requests.
-     </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry>
-     <term><literal>sru2z3950</literal> (filter)</term>
-     <listitem>
-      <para>
-       Translate SRU requests into Z39.50 requests.
-     </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry>
      <term><literal>sru_client</literal> (sink)</term>
      <listitem>
       <para>
-       SRU searching and retrieval.
-      </para>
-     </listitem>
-    </varlistentry>
-    <varlistentry>
-     <term><literal>srw_client</literal> (sink)</term>
-     <listitem>
-      <para>
-       SRW searching and retrieval.
+       SRU/GET and SRU/SOAP searching and retrieval.
       </para>
      </listitem>
     </varlistentry>
     implementation detail - they could just as well have been written
     in YAML or Lisp-like S-expressions, or in a custom syntax.)
    </para>
-   <para>
-    Since XML has been chosen, an XML schema,
-    <filename>config.xsd</filename>, is provided for validating
-    configuration files.  This file is supplied in the
-    <filename>etc</filename> directory of the Metaproxy distribution.  It
-    can be used by (among other tools) the <command>xmllint</command>
-    program supplied as part of the <literal>libxml2</literal>
-    distribution:
-   </para>
-   <screen>
-    xmllint --noout --schema etc/config.xsd my-config-file.xml
-   </screen>
-   <para>
-    (A recent version of <literal>libxml2</literal> is required, as
-    support for XML Schemas is a relatively recent addition.)
-   </para>
   </section>
   
   <section id="overview.xml.structure">
-   <title>Overview of XML structure</title>
+   <title>Overview of the config file XML structure</title>
    <para>
     All elements and attributes are in the namespace
-    <ulink url="http://indexdata.dk/yp2/config/1"/>.
+    <ulink url="http://indexdata.com/metaproxy"/>.
      This is most easily achieved by setting the default namespace on
      the top-level element, as here:
    </para>
    <screen>
-    &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
+    &lt;metaproxy xmlns="http://indexdata.com/metaproxy" version="1.0"&gt;
    </screen>
    <para>
-    The top-level element is &lt;yp2&gt;.  This contains a
+    The top-level element is &lt;metaproxy&gt;.  This contains a
     &lt;start&gt; element, a &lt;filters&gt; element and a
     &lt;routes&gt; element, in that order.  &lt;filters&gt; is
     optional; the other two are mandatory.  All three are
    <para>
     The following is a small, but complete, Metaproxy configuration
     file (included in the distribution as
-    <literal>metaproxy/etc/config0.xml</literal>).
+    <literal>metaproxy/etc/config1.xml</literal>).
     This file defines a very simple configuration that simply proxies
     to whatever back-end server the client requests, but logs each
     request and response.  This can be useful for debugging complex
     client-server dialogues.
    </para>
    <screen><![CDATA[<?xml version="1.0"?>
-<yp2 xmlns="http://indexdata.dk/yp2/config/1">
+<metaproxy xmlns="http://indexdata.com/metaproxy" version="1.0">
   <start route="start"/>
   <filters>
     <filter id="frontend" type="frontend_net">
       <filter refid="frontend"/>
       <filter type="log"/>
       <filter refid="backend"/>
+      <filter type="bounce"/>
     </route>
   </routes>
-</yp2>
+</metaproxy>
 ]]></screen>
    <para>
     It works by defining a single route, called
-    <literal>start</literal>, which consists of a sequence of three
+    <literal>start</literal>, which consists of a sequence of four
     filters.  The first and last of these are included by reference:
     their <literal>&lt;filter&gt;</literal> elements have
     <literal>refid</literal> attributes that refer to filters defined
     middle filter is included inline in the route.
    </para>
    <para>
-    The three filters in the route are as follows: first, a
+    The four filters in the route are as follows: first, a
     <literal>frontend_net</literal> filter accepts Z39.50 requests
     from any host on port 9000; then these requests are passed through
     a <literal>log</literal> filter that emits a message for each
     request; they are then fed into a <literal>z3950_client</literal>
-    filter, which forwards the requests to the client-specified
-    back-end Z39.509 server.  When the response arrives, it is handed
+    filter, which forwards all Z39.50 requests to the client-specified
+    back-end Z39.509 server. Those Z39.50 packages are returned by the
+    <literal>z3950_client</literal> filter, with the response data
+    filled by the external Z39.50 server targeted.
+    All non-Z39.50 packages are passed through to the
+    <literal>bounce</literal> filter, which definitely bounces
+    everything, including fish, bananas, cold pyjamas,
+    mutton, beef and trout packages.
+    When the response arrives, it is handed
     back to the <literal>log</literal> filter, which emits another
-    message; and then to the front-end filter, which returns the
-    response to the client.
+    message; and then to the <literal>frontend_net</literal> filter, 
+    which returns the response to the client.
    </para>
   </section>
+  <section id="checking.xml.syntax">
+   <title>Config file syntax checking</title>
+   <para>
+    The distribution contains RelaxNG Compact and XML syntax checking
+    files, as well as XML Schema files. These are found in the
+    distribution paths 
+   <screen>
+    xml/schema/metaproxy.rnc
+    xml/schema/metaproxy.rng
+    xml/schema/metaproxy.xsd
+   </screen>
+    and can be used to verify or debug the XML structure of
+    configuration files. For example, using the utility
+    <filename>xmllint</filename>, syntax checking is done like this:
+   <screen>
+    xmllint --noout --schema xml/schema/metaproxy.xsd etc/config-local.xml 
+    xmllint --noout --relaxng xml/schema/metaproxy.rng etc/config-local.xml 
+   </screen>
+    (A recent version of <literal>libxml2</literal> is required, as
+    support for XML Schemas is a relatively recent addition.)
+   </para>
+   <para>
+    You can of course use any other RelaxNG or XML Schema compliant tool
+    you wish.
+   </para>
+   </section>
  </chapter>
 
 
     The interaction between
     these two filters is necessarily complex: it reflects the real,
     irreducible complexity of multi-database searching in a protocol such
-    as Z39.50 that separates initialisation from searching, and in
-    which the database to be searched is not known at initialisation
+    as Z39.50 that separates initialization from searching, and in
+    which the database to be searched is not known at initialization
     time.
    </para>
    <para>
     It's possible to use these filters without understanding the
     details of their functioning and the interaction between them; the
-    next two sections of this chapter are ``HOWTO'' guides for doing
+    next two sections of this chapter are ``HOW-TO'' guides for doing
     just that.  However, debugging complex configurations will require
     a deeper understanding, which the last two sections of this
     chapters attempt to provide.
   </virtual>
   <virtual>
     <database>marc</database>
-    <target>indexdata.dk/marc</target>
+    <target>indexdata.com/marc</target>
   </virtual>
 </filter>]]></screen>
    <para>
     Index Data's tiny testing database of MARC records:
    </para>
    <screen><![CDATA[<?xml version="1.0"?>
-<yp2 xmlns="http://indexdata.dk/yp2/config/1">
+<metaproxy xmlns="http://indexdata.com/metaproxy" version="1.0">
   <start route="start"/>
   <routes>
     <route id="start">
         </virtual>
         <virtual>
           <database>marc</database>
-          <target>indexdata.dk/marc</target>
+          <target>indexdata.com/marc</target>
         </virtual>
         <virtual>
           <database>all</database>
           <target>z3950.loc.gov:7090/voyager</target>
-          <target>indexdata.dk/marc</target>
+          <target>indexdata.com/marc</target>
         </virtual>
       </filter>
       <filter type="multi"/>
       <filter type="z3950_client">
         <timeout>30</timeout>
       </filter>
+      <filter type="bounce"/>
     </route>
   </routes>
-</yp2>]]></screen>
+</metaproxy>]]></screen>
    <para>
     (Using a
     <literal>virt_db</literal>
@@ -1246,7 +1364,7 @@ Z>
     can be inconvenient in deployment, when users typically don't want
     to be bothered with problems of this kind and prefer just to get
     the records from the databases that are available.  To obtain this
-    latter behaviour add an empty
+    latter behavior add an empty
     <literal>&lt;hideunavailable&gt;</literal>
     element inside the
     <literal>multi</literal> filter:
@@ -1381,9 +1499,8 @@ Z>
        [Here there should be a diagram showing the progress of
        packages through the filters during a simple virtual-database
        search and a multi-database search, but is seems that your
-       toolchain has not been able to include the diagram in this
-       document.  This is because of LaTeX suckage.  Time to move to
-       OpenOffice.  Yes, really.]
+       tool chain has not been able to include the diagram in this
+       document.]
       </phrase>
      </textobject>
 <!-- ### This used to work with an older version of DocBook
@@ -1430,7 +1547,7 @@ Z>
    <para>
     This chapter contains documentation of the Metaproxy source code, and is
     of interest only to maintainers and developers.  If you need to
-    change Metaproxy's behaviour or write a new filter, then you will most
+    change Metaproxy's behavior or write a new filter, then you will most
     likely find this chapter helpful.  Otherwise it's a waste of your
     good time.  Seriously: go and watch a film or something.
     <citetitle>This is Spinal Tap</citetitle> is particularly good.
@@ -1492,11 +1609,11 @@ Z>
     <para>
      The virtual base class of all filters.  The filter API is, on the
      surface at least, extremely simple: two methods.
-     <literal>configure()</literal> is passed a DOM tree representing
+     <literal>configure()</literal> is passed an XML DOM tree representing
      that part of the configuration file that pertains to this filter
      instance, and is expected to walk that tree extracting relevant
      information.  And <literal>process()</literal> processes a
-     package (see below).  That surface simplicitly is a bit
+     package (see below).  That surface simplicity is a bit
      misleading, as <literal>process()</literal> needs to know a lot
      about the <literal>Package</literal> class in order to do
      anything useful.
@@ -1514,12 +1631,7 @@ Z>
      <filename>filter_*.cpp</filename> respectively.  All the header
      files should be pretty much identical, in that they declare the
      class, including a private <literal>Rep</literal> class and a
-     member pointer to it, and the two public methods.  The only extra
-     information in any filter header is additional private types and
-     members (which should really all be in the <literal>Rep</literal>
-     anyway) and private methods (which should also remain known only
-     to the source file, but C++'s brain-damaged design requires this
-     dirty laundry to be exhibited in public.  Thanks, Bjarne!)
+     member pointer to it, and the two public methods.
     </para>
     <para>
      The source file for each filter needs to supply:
@@ -1667,31 +1779,20 @@ Z>
    </para>
   </section>
  </chapter>
-
-
-
- <chapter id="refguide">
+ <reference id="refguide">
   <title>Reference guide</title>
-  <para>
-   The material in this chapter is drawn directly from the individual
-   manual entries.  In particular, the Metaproxy invocation section is
-   available using <command>man metaproxy</command>, and the section
-   on each individual filter is available using the name of the filter
-   as the argument to the <command>man</command> command.
-  </para>
-
-
-  <section id="progref">
-   <title>Metaproxy invocation</title>
-   &progref;
-  </section>
-
-
-  <section id="filterref">
-   <title>Reference guide to Metaproxy filters</title>
-   &manref;
-  </section>
- </chapter>
+    <para>
+     The material in this chapter is drawn directly from the individual
+     manual entries.  In particular, the Metaproxy invocation section is
+     available using <command>man metaproxy</command>, and the section
+     on each individual filter is available using the name of the filter
+     as the argument to the <command>man</command> command.
+    </para>
+    &manref;
+ </reference>
 </book>
 
  <!-- Keep this comment at the end of the file