Describe <hideunavailable>
[metaproxy-moved-to-github.git] / doc / book.xml
1 <!-- $Id: book.xml,v 1.31 2006-05-16 10:32:54 mike Exp $ -->
2  <bookinfo>
3   <title>Metaproxy - User's Guide and Reference</title>
4   <author>
5    <firstname>Mike</firstname><surname>Taylor</surname>
6   </author>
7   <author>
8    <firstname>Adam</firstname><surname>Dickmeiss</surname>
9   </author>
10   <copyright>
11    <year>2006</year>
12    <holder>Index Data ApS</holder>
13   </copyright>
14   <abstract>
15    <simpara>
16     Metaproxy is a universal router, proxy and encapsulated
17     metasearcher for information retrieval protocols.  It accepts,
18     processes, interprets and redirects requests from IR clients using
19     standard protocols such as
20     <ulink url="&url.z39.50;">ANSI/NISO Z39.50</ulink>
21     (and in the future <ulink url="&url.sru;">SRU</ulink>
22     and <ulink url="&url.srw;">SRW</ulink>), as
23     well as functioning as a limited
24     <ulink url="&url.http;">HTTP</ulink> server. 
25     Metaproxy is configured by an XML file which
26     specifies how the software should function in terms of routes that
27     the request packets can take through the proxy, each step on a
28     route being an instantiation of a filter.  Filters come in many
29     types, one for each operation: accepting Z39.50 packets, logging,
30     query transformation, multiplexing, etc.  Further filter-types can
31     be added as loadable modules to extend Metaproxy functionality,
32     using the filter API.
33    </simpara>
34    <simpara>
35     The terms under which Metaproxy will be distributed have yet to be
36     established, but it will not necessarily be open source; so users
37     should not at this stage redistribute the code without explicit
38     written permission from the copyright holders, Index Data ApS.
39    </simpara>
40    <simpara>
41     <inlinemediaobject>
42      <imageobject>
43       <imagedata fileref="common/id.png" format="PNG"/>
44      </imageobject>
45      <imageobject>
46       <imagedata fileref="common/id.eps" format="EPS"/>
47      </imageobject>
48     </inlinemediaobject>
49    </simpara>
50   </abstract>
51  </bookinfo>
52
53  <chapter id="introduction">
54   <title>Introduction</title>
55   
56   
57   <para>
58    <ulink url="&url.metaproxy;">Metaproxy</ulink>
59    is a standalone program that acts as a universal router, proxy and
60    encapsulated metasearcher for information retrieval protocols such
61    as <ulink url="&url.z39.50;">Z39.50</ulink>, and in the future
62    <ulink url="&url.sru;">SRU</ulink> and <ulink url="&url.srw;">SRW</ulink>.
63    To clients, it acts as a server of these protocols: it can be searched,
64    records can be retrieved from it, etc. 
65    To servers, it acts as a client: it searches in them,
66    retrieves records from them, etc.  it satisfies its clients'
67    requests by transforming them, multiplexing them, forwarding them
68    on to zero or more servers, merging the results, transforming
69    them, and delivering them back to the client.  In addition, it
70    acts as a simple <ulink url="&url.http;">HTTP</ulink> server; support
71    for further protocols can be added in a modular fashion, through the
72    creation of new filters.
73   </para>
74   <screen>
75    Anything goes in!
76    Anything goes out!
77    Fish, bananas, cold pyjamas,
78    Mutton, beef and trout!
79         - attributed to Cole Porter.
80   </screen>
81   <para>
82    Metaproxy is a more capable alternative to
83    <ulink url="&url.yazproxy;">YAZ Proxy</ulink>,
84    being more powerful, flexible, configurable and extensible.  Among
85    its many advantages over the older, more pedestrian work are
86    support for multiplexing (encapsulated metasearching), routing by
87    database name, authentication and authorisation and serving local
88    files via HTTP.  Equally significant, its modular architecture
89    facilitites the creation of pluggable modules implementing further
90    functionality.
91   </para>
92   <para>
93    This manual will briefly describe Metaproxy's licensing situation
94    before giving an overview of its architecture, then discussing the
95    key concept of a filter in some depth and giving an overview of
96    the various filter types, then discussing the configuration file
97    format.  After this come several optional chapters which may be
98    freely skipped: a detailed discussion of virtual databases and
99    multi-database searching, some notes on writing extensions
100    (additional filter types) and a high-level description of the
101    source code.  Finally comes the reference guide, which contains
102    instructions for invoking the <command>metaproxy</command>
103    program, and detailed information on each type of filter,
104    including examples.
105   </para>
106  </chapter>
107
108
109
110  <chapter id="licence">
111   <title>The Metaproxy Licence</title>
112   <para>
113    <emphasis role="strong">
114     No decision has yet been made on the terms under which
115     Metaproxy will be distributed.
116    </emphasis>
117    It is possible that, unlike
118    other Index Data products, metaproxy may not be released under a
119    free-software licence such as the GNU GPL.  Until a decision is
120    made and a public statement made, then, and unless it has been
121    delivered to you other specific terms, please treat Metaproxy as
122    though it were proprietary software.
123    The code should not be redistributed without explicit
124    written permission from the copyright holders, Index Data ApS.
125   </para>
126  </chapter>
127
128  <chapter id="installation">
129   <title>Installation</title>
130   <para>
131    Metaproxy depends on the following tools/libraries:
132    <variablelist>
133     <varlistentry><term><ulink url="&url.yazplusplus;">YAZ++</ulink></term>
134      <listitem>
135       <para>
136        This is a C++ library based on <ulink url="&url.yaz;">YAZ</ulink>.
137       </para>
138      </listitem>
139     </varlistentry>
140     <varlistentry><term><ulink url="&url.libxslt;">Libxslt</ulink></term>
141      <listitem>
142       <para>This is an XSLT processor - based on 
143        <ulink url="&url.libxml2;">Libxml2</ulink>. Both Libxml2 and
144        Libxslt must be installed with the development components
145        (header files, etc.) as well as the run-time libraries.
146       </para>
147      </listitem>
148     </varlistentry>
149     <varlistentry><term><ulink url="&url.boost;">Boost</ulink></term>
150      <listitem>
151       <para>
152        The popular C++ library. Initial versions of Metaproxy
153        was built with 1.33.0. Version 1.33.1 works too.
154       </para>
155      </listitem>
156     </varlistentry>
157    </variablelist>
158   </para>
159   <para>
160    In order to compile Metaproxy a modern C++ compiler is
161    required. Boost, in particular, requires the C++ compiler
162    to facilitate the newest features. Refer to Boost
163    <ulink url="&url.boost.compilers.status;">Compiler Status</ulink>
164    for more information.
165   </para>
166   <para>
167    We have succesfully built Metaproxy using the compilers
168    <ulink url="&url.gcc;">GCC</ulink> version 4.0 and
169    <ulink url="&url.vstudio;">Microsoft Visual Studio</ulink> 2003/2005.
170   </para>
171
172   <section id="installation.unix">
173    <title>Installation on Unix (from Source)</title>
174    <para>
175     Here is a quick step-by-step guide on how to compile all the
176     tools that Metaproxy uses. Only few systems have none of the required
177     tools binary packages. If, for example, Libxml2/libxslt are already
178     installed as development packages use those (and omit compilation).
179    </para>
180    
181    <para>
182     Libxml2/libxslt:
183    </para>
184    <screen>
185     gunzip -c libxml2-version.tar.gz|tar xf -
186     cd libxml2-version
187     ./configure
188     make
189     su
190     make install
191    </screen>
192    <screen>
193     gunzip -c libxslt-version.tar.gz|tar xf -
194     cd libxslt-version
195     ./configure
196     make
197     su
198     make install
199    </screen>
200    <para>
201     YAZ/YAZ++:
202    </para>
203    <screen>
204     gunzip -c yaz-version.tar.gz|tar xf -
205     cd yaz-version
206     ./configure
207     make
208     su
209     make install
210    </screen>
211    <screen>
212     gunzip -c yazpp-version.tar.gz|tar xf -
213     cd yazpp-version
214     ./configure
215     make
216     su
217     make install
218    </screen>
219    <para>
220     Boost:
221    </para>
222    <screen>
223     gunzip -c boost-version.tar.gz|tar xf -
224     cd boost-version
225     ./configure
226     make
227     su
228     make install
229    </screen>
230    <para>
231     Metaproxy:
232    </para>
233    <screen>
234     gunzip -c metaproxy-version.tar.gz|tar xf -
235     cd metaproxy-version
236     ./configure
237     make
238     su
239     make install
240    </screen>
241   </section>
242
243   <section id="installation.debian">
244    <title>Installation on Debian GNU/Linux</title>
245    <para>
246     All dependencies for Metaproxy are available as 
247     <ulink url="&url.debian;">Debian</ulink>
248     packages for the sarge (stable in 2005) and etch (testing in 2005)
249     distributions.
250    </para>
251    <para>
252     The procedures for Debian based systems, such as
253     <ulink url="&url.ubuntu;">Ubuntu</ulink> is probably similar
254    </para>
255    <para>
256     There is currently no official Debian package for YAZ++.
257     And the Debian package for YAZ is probably too old.
258     Update the <filename>/etc/apt/sources.list</filename>
259     to include the Index Data repository.
260     See YAZ' <ulink url="&url.yaz.download.debian;">Download Debian</ulink>
261     for more information.
262    </para>
263    <screen>
264     apt-get install libxslt1-dev
265     apt-get install libyazpp-dev
266     apt-get install libboost-dev
267     apt-get install libboost-thread-dev
268     apt-get install libboost-date-time-dev
269     apt-get install libboost-program-options-dev
270     apt-get install libboost-test-dev
271    </screen>
272    <para>
273     With these packages installed, the usual configure + make
274     procedure can be used for Metaproxy as outlined in
275     <xref linkend="installation.unix"/>.
276    </para>
277   </section>
278
279   <section id="installation.windows">
280    <title>Installation on Windows</title>
281    <para>
282     Metaproxy can be compiled with Microsoft
283     <ulink url="&url.vstudio;">Visual Studio</ulink>.
284     Version 2003 (C 7.1) and 2005 (C 8.0) is known to work.
285    </para>
286    <section id="installation.windows.boost">
287     <title>Boost</title>
288     <para>
289      Get Boost from its <ulink url="&url.boost;">home page</ulink>.
290      You also need Boost Jam (an alternative to make).
291      That's also available from the Boost home page.
292      The files to be downloaded are called something like:
293      <filename>boost_1_33-1.exe</filename>
294      and
295      <filename>boost-jam-3.1.12-1-ntx86.zip</filename>.
296      Unpack Boost Jam first. Put <filename>bjam.exe</filename>
297      in your system path. Make a command prompt and ensure
298      it can be found automatically. If not check the PATH.
299      The Boost .exe is a self-extracting exe with
300      complete source for Boost. Compile that source with
301      Boost Jam (An alternative to Make).
302      The compilation takes a while.
303      For Visual Studio 2003, use
304      <screen>
305       bjam "-sTOOLS=vc-7_1"
306      </screen>
307      Here <literal>vc-7_1</literal> refers to a "Toolset" (compiler system).
308      For Visual Studio 2005, use
309      <screen>
310       bjam "-sTOOLS=vc-8_0"
311      </screen>
312      To install the libraries in a common place, use
313      <screen>
314       bjam "-sTOOLS=vc-7_1" install
315      </screen>
316      (or vc-8_0 for VS 2005).
317     </para>
318     <para>
319      By default, the Boost build process installs the resulting
320      libraries + header files in
321      <literal>\boost\lib</literal>, <literal>\boost\include</literal>.
322     </para>
323     <para>
324      For more informatation about installing Boost refer to the
325      <ulink url="&url.boost.getting.started;">getting started</ulink>
326      pages.
327     </para>
328    </section>
329
330    <section id="installation.windows.libxslt">
331     <title>Libxslt</title>
332     <para>
333      <ulink url="&url.libxslt;">Libxslt</ulink> can be downloaded
334      for Windows from
335      <ulink url="&url.libxml2.download.win32;">here</ulink>.
336     </para>
337     <para>
338      Libxslt has other dependencies, but thes can all be downloaded
339      from the same site. Get the following:
340      iconv, zlib, libxml2, libxslt.
341     </para>
342    </section>
343
344    <section id="installation.windows.yaz">
345     <title>YAZ</title>
346     <para>
347      <ulink url="&url.yaz;">YAZ</ulink> can be downloaded
348      for Windows from
349      <ulink url="&url.yaz.download.win32;">here</ulink>.
350     </para>
351    </section>
352
353    <section id="installation.windows.yazplusplus">
354     <title>YAZ++</title>
355     <para>
356      Get <ulink url="&url.yazplusplus;">YAZ++</ulink> as well.
357      Version 1.0 or later is required. For now get it from
358      Index Data's
359      <ulink url="&url.snapshot.download;">Snapshot area</ulink>.
360     </para>
361     <para>
362      YAZ++ includes NMAKE makefiles, similar to those found in the
363      YAZ package.
364     </para>
365    </section>
366
367    <section id="installation.windows.metaproxy">
368     <title>Metaproxy</title>
369     <para>
370      Metaproxy is shipped with NMAKE makfiles as well - similar
371      to those found in the YAZ++/YAZ packages. Adjust this Makefile
372      to point to the proper locations of Boost, Libxslt, Libxml2,
373      zlib, iconv, yaz and yazpp.
374     </para>
375
376     <variablelist>
377      <varlistentry><term><literal>DEBUG</literal></term>
378       <listitem><para>
379         If set to 1, the software is
380         compiled with debugging libraries (code generation is
381         multi-threaded debug DLL).
382         If set to 0, the software is compiled with release libraries
383         (code generation is multi-threaded DLL).
384        </para></listitem>
385      </varlistentry>
386
387      <varlistentry>
388       <term><literal>BOOST</literal></term>
389       <listitem>
390        <para>
391         Boost install location
392        </para>
393       </listitem>
394      </varlistentry>
395
396      <varlistentry>
397       <term><literal>BOOST_VERSION</literal></term>
398       <listitem>
399        <para>
400         Boost version (replace . with _).
401        </para>
402       </listitem>
403      </varlistentry>
404
405      <varlistentry>
406       <term><literal>BOOST_TOOLSET</literal></term>
407       <listitem>
408        <para>
409         Boost toolset.
410        </para>
411       </listitem>
412      </varlistentry>
413
414      <varlistentry>
415       <term><literal>LIBXSLT_DIR</literal>,
416        <literal>LIBXML2_DIR</literal> ..</term>
417       <listitem>
418        <para>
419         Specify the locations of Libxslt, libiconv, libxml2 and
420         libxslt.
421        </para>
422       </listitem>
423      </varlistentry>
424       
425     </variablelist>
426     
427     <para>
428      After succesful compilation you'll find
429      <literal>metaproxy.exe</literal> in the
430      <literal>bin</literal> directory.
431     </para>
432    </section>
433
434
435   </section>
436  </chapter>
437  
438  <chapter id="architecture">
439   <title>The Metaproxy Architecture</title>
440   <para>
441    The Metaproxy architecture is based on three concepts:
442    the <emphasis>package</emphasis>,
443    the <emphasis>route</emphasis>
444    and the <emphasis>filter</emphasis>.
445   </para>
446   <variablelist>
447    <varlistentry>
448     <term>Packages</term>
449     <listitem>
450      <para>
451       A package is request or response, encoded in some protocol,
452       issued by a client, making its way through Metaproxy, send to or
453       received from a server, or sent back to the client.
454      </para>
455      <para>
456       The core of a package is the protocol unit - for example, a
457       Z39.50 Init Request or Search Response, or an SRU searchRetrieve
458       URL or Explain Response.  In addition to this core, a package
459       also carries some extra information added and used by Metaproxy
460       itself.
461      </para>
462      <para>
463       In general, packages are doctored as they pass through
464       Metaproxy.  For example, when the proxy performs authentication
465       and authorisation on a Z39.50 Init request, it removes the
466       authentication credentials from the package so that they are not
467       passed onto the back-end server; and when search-response
468       packages are obtained from multiple servers, they are merged
469       into a single unified package that makes its way back to the
470       client.
471      </para>
472     </listitem>
473    </varlistentry>
474    <varlistentry>
475     <term>Routes</term>
476     <listitem>
477      <para>
478       Packages make their way through routes, which can be thought of
479       as programs that operate on the package data-type.  Each
480       incoming package initially makes its way through a default
481       route, but may be switched to a different route based on various
482       considerations.  Routes are made up of sequences of filters (see
483       below).
484      </para>
485     </listitem>
486    </varlistentry>
487    <varlistentry>
488     <term>Filters</term>
489     <listitem>
490      <para>
491       Filters provide the individual instructions within a route, and
492       effect the necessary transformations on packages.  A particular
493       configuration of Metaproxy is essentially a set of filters,
494       described by configuration details and arranged in order in one
495       or more routes.  There are many kinds of filter - about a dozen
496       at the time of writing with more appearing all the time - each
497       performing a specific function and configured by different
498       information.
499      </para>
500      <para>
501       The word ``filter'' is sometimes used rather loosely, in two
502       different ways: it may be used to mean a particular
503       <emphasis>type</emphasis> of filter, as when we speak of ``the
504       auth_simplefilter'' or ``the multi filter''; or it may be used
505       to be a specific <emphasis>instance</emphasis> of a filter
506       within a Metaproxy configuration.  For example, a single
507       configuration will often contain multiple instances of the
508       <literal>z3950_client</literal> filter.  In
509       operational terms, of these is a separate filter.  In practice,
510       context always make it clear which sense of the word ``filter''
511       is being used.
512      </para>
513      <para>
514       Extensibility of Metaproxy is primarily through the creation of
515       plugins that provide new filters.  The filter API is small and
516       conceptually simple, but there are many details to master.  See
517       the section below on
518       <link linkend="extensions">extensions</link>.
519      </para>
520     </listitem>
521    </varlistentry>
522   </variablelist>
523   <para>
524    Since packages are created and handled by the system itself, and
525    routes are conceptually simple, most of the remainder of this
526    document concentrates on filters.  After a brief overview of the
527    filter types follows, along with some thoughts on possible future
528    directions.
529   </para>
530  </chapter>
531
532
533
534  <chapter id="filters">
535   <title>Filters</title>
536   
537   
538   <section>
539    <title>Introductory notes</title>
540    <para>
541     It's useful to think of Metaproxy as an interpreter providing a small
542     number of primitives and operations, but operating on a very
543     complex data type, namely the ``package''.
544    </para>
545    <para>
546     A package represents a Z39.50 or SRU/W request (whether for Init,
547     Search, Scan, etc.)  together with information about where it came
548     from.  Packages are created by front-end filters such as
549     <literal>frontend_net</literal> (see below), which reads them from
550     the network; other front-end filters are possible.  They then pass
551     along a route consisting of a sequence of filters, each of which
552     transforms the package and may also have side-effects such as
553     generating logging.  Eventually, the route will yield a response,
554     which is sent back to the origin.
555    </para>
556    <para>
557     There are many kinds of filter: some that are defined statically
558     as part of Metaproxy, and others may be provided by third parties
559     and dynamically loaded.  They all conform to the same simple API
560     of essentially two methods: <function>configure()</function> is
561     called at startup time, and is passed a DOM tree representing that
562     part of the configuration file that pertains to this filter
563     instance: it is expected to walk that tree extracting relevant
564     information; and <function>process()</function> is called every
565     time the filter has to processes a package.
566    </para>
567    <para>
568     While all filters provide the same API, there are different modes
569     of functionality.  Some filters are sources: they create
570     packages
571     (<literal>frontend_net</literal>);
572     others are sinks: they consume packages and return a result
573     (<literal>z3950_client</literal>,
574     <literal>backend_test</literal>,
575     <literal>http_file</literal>);
576     the others are true filters, that read, process and pass on the
577     packages they are fed
578     (<literal>auth_simple</literal>,
579     <literal>log</literal>,
580     <literal>multi</literal>,
581     <literal>query_rewrite</literal>,
582     <literal>session_shared</literal>,
583     <literal>template</literal>,
584     <literal>virt_db</literal>).
585    </para>
586  </section>
587   
588   
589   <section id="overview.filter.types">
590    <title>Overview of filter types</title>
591    <para>
592     We now briefly consider each of the types of filter supported by
593     the core Metaproxy binary.  This overview is intended to give a
594     flavour of the available functionality; more detailed information
595     about each type of filter is included below in
596     <link linkend="filterref"
597           >the reference guide to Metaproxy filters</link>.
598    </para>
599    <para>
600     The filters are here named by the string that is used as the
601     <literal>type</literal> attribute of a
602     <literal>&lt;filter&gt;</literal> element in the configuration
603     file to request them, with the name of the class that implements
604     them in parentheses.  (The classname is not needed for normal
605     configuration and use of Metaproxy; it is useful only to
606     developers.)
607    </para>
608    <para>
609     The filters are here listed in alphabetical order:
610    </para>
611    
612    <section>
613     <title><literal>auth_simple</literal>
614      (mp::filter::AuthSimple)</title>
615     <para>
616      Simple authentication and authorisation.  The configuration
617      specifies the name of a file that is the user register, which
618      lists <varname>username</varname>:<varname>password</varname>
619      pairs, one per line, colon separated. When a session begins, it
620      is rejected unless username and passsword are supplied, and match
621      a pair in the register.  The configuration file may also specific
622      the name of another file that is the target register: this lists
623      lists <varname>username</varname>:<varname>dbname</varname>,<varname>dbname</varname>...
624      sets, one per line, with multiple database names separated by
625      commas.  When a search is processed, it is rejected unless the
626      database to be searched is one of those listed as available to
627      the user.
628     </para>
629    </section>
630    
631    <section>
632     <title><literal>backend_test</literal>
633     (mp::filter::Backend_test)</title>
634     <para>
635      A sink that provides dummy responses in the manner of the
636      <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
637      for testing.  Seriously, you don't need this.  Pretend you didn't
638      even read this section.
639     </para>
640    </section>
641    
642    <section>
643     <title><literal>frontend_net</literal>
644      (mp::filter::FrontendNet)</title>
645     <para>
646      A source that accepts Z39.50 connections from a port
647      specified in the configuration, reads protocol units, and
648      feeds them into the next filter in the route.  When the result is
649      revceived, it is returned to the original origin.
650     </para>
651    </section>
652
653    <section>
654     <title><literal>http_file</literal>
655      (mp::filter::HttpFile)</title>
656     <para>
657      A sink that returns the contents of files from the local
658      filesystem in response to HTTP requests.  (Yes, Virginia, this
659      does mean that Metaproxy is also a Web-server in its spare time.  So
660      far it does not contain either an email-reader or a Lisp
661      interpreter, but that day is surely coming.)
662     </para>
663    </section>
664    
665    <section>
666     <title><literal>log</literal>
667      (mp::filter::Log)</title>
668     <para>
669      Writes logging information to standard output, and passes on
670      the package unchanged.
671    </para>
672    </section>
673    
674    <section>
675    <title><literal>multi</literal>
676      (mp::filter::Multi)</title>
677     <para>
678      Performs multi-database searching.
679      See
680      <link linkend="multidb">the extended discussion</link>
681      of virtual databases and multi-database searching below.
682     </para>
683    </section>
684    
685    <section>
686    <title><literal>query_rewrite</literal>
687      (mp::filter::QueryRewrite)</title>
688     <para>
689      Rewrites Z39.50 Type-1 and Type-101 (``RPN'') queries by a
690      three-step process: the query is transliterated from Z39.50
691      packet structures into an XML representation; that XML
692      representation is transformed by an XSLT stylesheet; and the
693      resulting XML is transliterated back into the Z39.50 packet
694      structure.
695     </para>
696    </section>
697    
698    <section>
699     <title><literal>session_shared</literal>
700      (mp::filter::SessionShared)</title>
701     <para>
702      When this is finished, it will implement global sharing of
703      result sets (i.e. between threads and therefore between
704      clients), yielding performance improvements especially when
705      incoming requests are from a stateless environment such as a
706      web-server, in which the client process representing a session
707      might be any one of many.  However:
708     </para>
709     <warning>
710      <para>
711       This filter is not yet completed.
712      </para>
713     </warning>
714    </section>
715    
716    <section>
717     <title><literal>template</literal>
718      (mp::filter::Template)</title>
719     <para>
720      Does nothing at all, merely passing the packet on.  (Maybe it
721      should be called <literal>nop</literal> or
722      <literal>passthrough</literal>?)  This exists not to be used, but
723      to be copied - to become the skeleton of new filters as they are
724      written.  As with <literal>backend_test</literal>, this is not
725      intended for civilians.
726     </para>
727    </section>
728    
729    <section>
730     <title><literal>virt_db</literal>
731      (mp::filter::Virt_db)</title>
732     <para>
733      Performs virtual database selection: based on the name of the
734      database in the search request, a server is selected, and its
735      address added to the request in a <literal>VAL_PROXY</literal>
736      otherInfo packet.  It will subsequently be used by a
737      <literal>z3950_client</literal> filter.
738      See
739      <link linkend="multidb">the extended discussion</link>
740      of virtual databases and multi-database searching below.
741     </para>
742    </section>
743    
744    <section>
745     <title><literal>z3950_client</literal>
746      (mp::filter::Z3950Client)</title>
747     <para>
748      Performs Z39.50 searching and retrieval by proxying the
749      packages that are passed to it.  Init requests are sent to the
750      address specified in the <literal>VAL_PROXY</literal> otherInfo
751      attached to the request: this may have been specified by client,
752      or generated by a <literal>virt_db</literal> filter earlier in
753      the route.  Subsequent requests are sent to the same address,
754      which is remembered at Init time in a Session object.
755     </para>
756   </section>
757   </section>
758   
759   
760   <section id="future.directions">
761    <title>Future directions</title>
762   <para>
763     Some other filters that do not yet exist, but which would be
764     useful, are briefly described.  These may be added in future
765     releases (or may be created by third parties, as loadable
766     modules).
767    </para>
768
769    <variablelist>
770     <varlistentry>
771      <term><literal>frontend_cli</literal> (source)</term>
772     <listitem>
773       <para>
774        Command-line interface for generating requests.
775       </para>
776      </listitem>
777     </varlistentry>
778     <varlistentry>
779      <term><literal>frontend_sru</literal> (source)</term>
780      <listitem>
781       <para>
782        Receive SRU (and perhaps SRW) requests.
783      </para>
784      </listitem>
785     </varlistentry>
786     <varlistentry>
787      <term><literal>sru2z3950</literal> (filter)</term>
788      <listitem>
789       <para>
790        Translate SRU requests into Z39.50 requests.
791      </para>
792      </listitem>
793     </varlistentry>
794     <varlistentry>
795      <term><literal>sru_client</literal> (sink)</term>
796      <listitem>
797       <para>
798        SRU searching and retrieval.
799       </para>
800      </listitem>
801     </varlistentry>
802     <varlistentry>
803      <term><literal>srw_client</literal> (sink)</term>
804      <listitem>
805       <para>
806        SRW searching and retrieval.
807       </para>
808      </listitem>
809     </varlistentry>
810     <varlistentry>
811      <term><literal>opensearch_client</literal> (sink)</term>
812      <listitem>
813       <para>
814        A9 OpenSearch searching and retrieval.
815       </para>
816      </listitem>
817     </varlistentry>
818    </variablelist>
819   </section>
820  </chapter>
821  
822  
823  
824  <chapter id="configuration">
825   <title>Configuration: the Metaproxy configuration file format</title>
826   
827   
828   <section>
829    <title>Introductory notes</title>
830    <para>
831     If Metaproxy is an interpreter providing operations on packages, then
832     its configuration file can be thought of as a program for that
833     interpreter.  Configuration is by means of a single file, the name
834     of which is supplied as the sole command-line argument to the
835     <command>metaproxy</command> program.  (See
836     <link linkend="progref">the reference guide</link>
837     below for more information on invoking Metaproxy.)
838    </para>
839    <para>
840     The configuration files are written in XML.  (But that's just an
841     implementation detail - they could just as well have been written
842     in YAML or Lisp-like S-expressions, or in a custom syntax.)
843    </para>
844    <para>
845     Since XML has been chosen, an XML schema,
846     <filename>config.xsd</filename>, is provided for validating
847     configuration files.  This file is supplied in the
848     <filename>etc</filename> directory of the Metaproxy distribution.  It
849     can be used by (among other tools) the <command>xmllint</command>
850     program supplied as part of the <literal>libxml2</literal>
851     distribution:
852    </para>
853    <screen>
854     xmllint --noout --schema etc/config.xsd my-config-file.xml
855    </screen>
856    <para>
857     (A recent version of <literal>libxml2</literal> is required, as
858     support for XML Schemas is a relatively recent addition.)
859    </para>
860   </section>
861   
862   <section id="overview.xml.structure">
863    <title>Overview of XML structure</title>
864    <para>
865     All elements and attributes are in the namespace
866     <ulink url="http://indexdata.dk/yp2/config/1"/>.
867      This is most easily achieved by setting the default namespace on
868      the top-level element, as here:
869    </para>
870    <screen>
871     &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
872    </screen>
873    <para>
874     The top-level element is &lt;yp2&gt;.  This contains a
875     &lt;start&gt; element, a &lt;filters&gt; element and a
876     &lt;routes&gt; element, in that order.  &lt;filters&gt; is
877     optional; the other two are mandatory.  All three are
878     non-repeatable.
879    </para>
880   <para>
881     The &lt;start&gt; element is empty, but carries a
882     <literal>route</literal> attribute, whose value is the name of
883     route at which to start running - analogous to the name of the
884     start production in a formal grammar.
885    </para>
886   <para>
887     If present, &lt;filters&gt; contains zero or more &lt;filter&gt;
888     elements.  Each filter carries a <literal>type</literal> attribute
889     which specifies what kind of filter is being defined
890     (<literal>frontend_net</literal>, <literal>log</literal>, etc.)
891     and contain various elements that provide suitable configuration
892     for a filter of its type.  The filter-specific elements are
893     described in
894     <link linkend="filterref">the reference guide below</link>.
895     Filters defined in this part of the file must carry an
896     <literal>id</literal> attribute so that they can be referenced
897     from elsewhere.
898    </para>
899    <para>
900     &lt;routes&gt; contains one or more &lt;route&gt; elements, each
901     of which must carry an <literal>id</literal> element.  One of the
902     routes must have the ID value that was specified as the start
903     route in the &lt;start&gt; element's <literal>route</literal>
904     attribute.  Each route contains zero or more &lt;filter&gt;
905     elements.  These are of two types.  They may be empty, but carry a
906     <literal>refid</literal> attribute whose value is the same as the
907     <literal>id</literal> of a filter previously defined in the
908     &lt;filters&gt; section.  Alternatively, a route within a filter
909     may omit the <literal>refid</literal> attribute, but contain
910     configuration elements similar to those used for filters defined
911     in the &lt;filters&gt; section.  (In other words, each filter in a
912     route may be included either by reference or by physical
913     inclusion.)
914    </para>
915   </section>
916
917
918   <section id="example.configuration">
919    <title>An example configuration</title>
920    <para>
921     The following is a small, but complete, Metaproxy configuration
922     file (included in the distribution as
923     <literal>metaproxy/etc/config0.xml</literal>).
924     This file defines a very simple configuration that simply proxies
925     to whatever back-end server the client requests, but logs each
926     request and response.  This can be useful for debugging complex
927     client-server dialogues.
928    </para>
929    <screen><![CDATA[<?xml version="1.0"?>
930 <yp2 xmlns="http://indexdata.dk/yp2/config/1">
931   <start route="start"/>
932   <filters>
933     <filter id="frontend" type="frontend_net">
934       <port>@:9000</port>
935     </filter>
936     <filter id="backend" type="z3950_client">
937     </filter>
938   </filters>
939   <routes>  
940     <route id="start">
941       <filter refid="frontend"/>
942       <filter type="log"/>
943       <filter refid="backend"/>
944     </route>
945   </routes>
946 </yp2>
947 ]]></screen>
948    <para>
949     It works by defining a single route, called
950     <literal>start</literal>, which consists of a sequence of three
951     filters.  The first and last of these are included by reference:
952     their <literal>&lt;filter&gt;</literal> elements have
953     <literal>refid</literal> attributes that refer to filters defined
954     within the prior <literal>&lt;filters&gt;</literal> section.  The
955     middle filter is included inline in the route.
956    </para>
957    <para>
958     The three filters in the route are as follows: first, a
959     <literal>frontend_net</literal> filter accepts Z39.50 requests
960     from any host on port 9000; then these requests are passed through
961     a <literal>log</literal> filter that emits a message for each
962     request; they are then fed into a <literal>z3950_client</literal>
963     filter, which forwards the requests to the client-specified
964     back-end Z39.509 server.  When the response arrives, it is handed
965     back to the <literal>log</literal> filter, which emits another
966     message; and then to the front-end filter, which returns the
967     response to the client.
968    </para>
969   </section>
970  </chapter>
971
972
973
974  <chapter id="multidb">
975   <title>Virtual databases and multi-database searching</title>
976
977
978   <section>
979    <title>Introductory notes</title>
980    <para>
981     Two of Metaproxy's filters are concerned with multiple-database
982     operations.  Of these, <literal>virt_db</literal> can work alone
983     to control the routing of searches to one of a number of servers,
984     while <literal>multi</literal> can work together with
985     <literal>virt_db</literal> to perform multi-database searching, merging
986     the results into a unified result-set - ``metasearch in a box''.
987    </para>
988    <para>
989     The interaction between
990     these two filters is necessarily complex: it reflects the real,
991     irreducible complexity of multi-database searching in a protocol such
992     as Z39.50 that separates initialisation from searching, and in
993     which the database to be searched is not known at initialisation
994     time.
995    </para>
996    <para>
997     It's possible to use these filters without understanding the
998     details of their functioning and the interaction between them; the
999     next two sections of this chapter are ``HOWTO'' guides for doing
1000     just that.  However, debugging complex configurations will require
1001     a deeper understanding, which the last two sections of this
1002     chapters attempt to provide.
1003    </para>
1004   </section>
1005
1006
1007   <section id="multidb.virt_db">
1008    <title>Virtual databases with the <literal>virt_db</literal> filter</title>
1009    <para>
1010     Working alone, the purpose of the
1011     <literal>virt_db</literal>
1012     filter is to route search requests to one of a selection of
1013     back-end databases.  In this way, a single Z39.50 endpoint
1014     (running Metaproxy) can provide access to several different
1015     underlying services, including those that would otherwise be
1016     inaccessible due to firewalls.  In many useful configurations, the
1017     back-end databases are local to the Metaproxy installation, but
1018     the software does not enforce this, and any valid Z39.50 servers
1019     may be used as back-ends.
1020    </para>
1021    <para>
1022     For example, a <literal>virt_db</literal>
1023     filter could be set up so that searches in the virtual database
1024     ``lc'' are forwarded to the Library of Congress bibliographic
1025     catalogue server, and searches in the virtual database ``marc''
1026     are forwarded to the toy database of MARC records that Index Data
1027     hosts for testing purposes.  A <literal>virt_db</literal>
1028     configuration to make this switch would look like this:
1029    </para>
1030    <screen><![CDATA[<filter type="virt_db">
1031   <virtual>
1032     <database>lc</database>
1033     <target>z3950.loc.gov:7090/voyager</target>
1034   </virtual>
1035   <virtual>
1036     <database>marc</database>
1037     <target>indexdata.dk/marc</target>
1038   </virtual>
1039 </filter>]]></screen>
1040    <para>
1041     As well as being useful in it own right, this filter also provides
1042     the foundation for multi-database searching.
1043    </para>
1044   </section>
1045
1046
1047   <section id="multidb.multi">
1048    <title>Multi-database search with the <literal>multi</literal> filter</title>
1049    <para>
1050     To arrange for Metaproxy to broadcast searches to multiple back-end
1051     servers, the configuration needs to include two components: a
1052     <literal>virt_db</literal>
1053     filter that specifies multiple
1054     <literal>&lt;target&gt;</literal>
1055     elements, and a subsequent
1056     <literal>multi</literal>
1057     filter.  Here, for example, is a complete configuration that
1058     broadcasts searches to both the Library of Congress catalogue and
1059     Index Data's tiny testing database of MARC records:
1060    </para>
1061    <screen><![CDATA[<?xml version="1.0"?>
1062 <yp2 xmlns="http://indexdata.dk/yp2/config/1">
1063   <start route="start"/>
1064   <routes>
1065     <route id="start">
1066       <filter type="frontend_net">
1067         <threads>10</threads>
1068         <port>@:9000</port>
1069       </filter>
1070       <filter type="virt_db">
1071         <virtual>
1072           <database>lc</database>
1073           <target>z3950.loc.gov:7090/voyager</target>
1074         </virtual>
1075         <virtual>
1076           <database>marc</database>
1077           <target>indexdata.dk/marc</target>
1078         </virtual>
1079         <virtual>
1080           <database>all</database>
1081           <target>z3950.loc.gov:7090/voyager</target>
1082           <target>indexdata.dk/marc</target>
1083         </virtual>
1084       </filter>
1085       <filter type="multi"/>
1086       <filter type="z3950_client">
1087         <timeout>30</timeout>
1088       </filter>
1089     </route>
1090   </routes>
1091 </yp2>]]></screen>
1092    <para>
1093     (Using a
1094     <literal>virt_db</literal>
1095     filter that specifies multiple
1096     <literal>&lt;target&gt;</literal>
1097     elements but without a subsequent
1098     <literal>multi</literal>
1099     filter yields surprising and undesirable results, as will be
1100     described below.  Don't do that.)
1101    </para>
1102    <para>
1103     Metaproxy can be invoked with this configuration as follows:
1104    </para>
1105    <screen>../src/metaproxy --config config-simple-multi.xml</screen>
1106    <para>
1107     And thereafter, Z39.50 clients can connect to the running server
1108     (on port 9000, as specified in the configuration) and search in
1109     any of the databases
1110     <literal>lc</literal> (the Library of Congress catalogue),
1111     <literal>marc</literal> (Index Data's test database of MARC records)
1112     or
1113     <literal>all</literal> (both of these).  As an example, a session
1114     using the YAZ command-line client <literal>yaz-client</literal> is
1115     here included (edited for brevity and clarity):
1116    </para>
1117    <screen><![CDATA[$ yaz-client @:9000
1118 Connecting...OK.
1119 Z> base lc
1120 Z> find computer
1121 Search was a success.
1122 Number of hits: 10000, setno 1
1123 Elapsed: 5.521070
1124 Z> base marc
1125 Z> find computer
1126 Search was a success.
1127 Number of hits: 10, setno 3
1128 Elapsed: 0.060187
1129 Z> base all
1130 Z> find computer
1131 Search was a success.
1132 Number of hits: 10010, setno 4
1133 Elapsed: 2.237648
1134 Z> show 1
1135 [marc]Record type: USmarc
1136 001    11224466
1137 003 DLC
1138 005 00000000000000.0
1139 008 910710c19910701nju           00010 eng
1140 010    $a 11224466
1141 040    $a DLC $c DLC
1142 050 00 $a 123-xyz
1143 100 10 $a Jack Collins
1144 245 10 $a How to program a computer
1145 260 1  $a Penguin
1146 263    $a 8710
1147 300    $a p. cm.
1148 Elapsed: 0.119612
1149 Z> show 2
1150 [VOYAGER]Record type: USmarc
1151 001 13339105
1152 005 20041229102447.0
1153 008 030910s2004    caua          000 0 eng
1154 035    $a (DLC)  2003112666
1155 906    $a 7 $b cbc $c orignew $d 4 $e epcn $f 20 $g y-gencatlg
1156 925 0  $a acquire $b 1 shelf copy $x policy default
1157 955    $a pc10 2003-09-10 $a pv12 2004-06-23 to SSCD; $h sj05 2004-11-30 $e sj05 2004-11-30 to Shelf.
1158 010    $a   2003112666
1159 020    $a 0761542892
1160 040    $a DLC $c DLC $d DLC
1161 050 00 $a MLCM 2004/03312 (G)
1162 245 10 $a 007, everything or nothing : $b Prima's official strategy guide / $c created by Kaizen Media Group.
1163 246 3  $a Double-O-seven, everything or nothing
1164 246 30 $a Prima's official strategy guide
1165 260    $a Roseville, CA : $b Prima Games, $c c2004.
1166 300    $a 161 p. : $b col. ill. ; $c 28 cm.
1167 500    $a "Platforms: Nintendo GameCube, Macintosh, PC, PlayStation 2 computer entertainment system, Xbox"--P. [4] of cover.
1168 650  0 $a Video games.
1169 710 2  $a Kaizen Media Group.
1170 856 42 $3 Publisher description $u http://www.loc.gov/catdir/description/random052/2003112666.html
1171 Elapsed: 0.150623
1172 Z>
1173 ]]></screen>
1174    <para>
1175     As can be seen, the first record in the result set is from the
1176     Index Data test database, and the second from the Library of
1177     Congress database.  The result-set continues alternating records
1178     round-robin style until the point where one of the databases'
1179     records are exhausted.
1180    </para>
1181    <para>
1182     This example uses only two back-end databases; more may be used.
1183     There is no limitation imposed on the number of databases that may
1184     be metasearched in this way: issues of resource usage and
1185     administrative complexity dictate the practical limits.
1186    </para>
1187    <para>
1188     What happens when one of the databases doesn't respond?  By default,
1189     the entire multi-database search fails, and the appropriate
1190     diagnostic is returned to the client.  This is usually appropriate
1191     during development, when technicians need maximum information, but
1192     can be inconvenient in deployment, when users typically don't want
1193     to be bothered with problems of this kind and prefer just to get
1194     the records from the databases that are available.  To obtain this
1195     latter behaviour add an empty
1196     <literal>&lt;hideunavailable&gt;</literal>
1197     element inside the
1198     <literal>&lt;multi&gt;</literal>:
1199    </para>
1200    <screen><![CDATA[      <filter type="multi">
1201         <hideunavailable/>
1202       </filter>]]></screen>
1203    <para>
1204     Under this regime, an error is reported to the client only if
1205     <emphasis>all</emphasis> the databases in a multi-database search
1206     are unavailable.
1207    </para>
1208   </section>
1209
1210
1211   <section id="multidb.what">
1212    <title>What's going on?</title>
1213    <warning>
1214     <title>Lark's vomit</title>
1215     <para>
1216      This section goes into a level of technical detail that is
1217      probably not necessary in order to configure and use Metaproxy.
1218      It is provided only for those who like to know how things work.
1219      You should feel free to skip on to the next section if this one
1220      doesn't seem like fun.
1221     </para>
1222    </warning>
1223    <para>
1224     Hold on tight - this may get a little hairy.
1225    </para>
1226    <para>
1227     In the general course of things, a Z39.50 Init request may carry
1228     with it an otherInfo packet of type <literal>VAL_PROXY</literal>,
1229     whose value indicates the address of a Z39.50 server to which the
1230     ultimate connection is to be made.  (This otherInfo packet is
1231     supported by YAZ-based Z39.50 clients and servers, but has not yet
1232     been ratified by the Maintenance Agency and so is not widely used
1233     in non-Index Data software.  We're working on it.)
1234     The <literal>VAL_PROXY</literal> packet functions
1235     analogously to the absoluteURI-style Request-URI used with the GET
1236     method when a web browser asks a proxy to forward its request: see
1237     the
1238     <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2"
1239            >Request-URI</ulink>
1240     section of
1241     <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616.html"
1242            >the HTTP 1.1 specification</ulink>.
1243    </para>
1244    <para>
1245     Within Metaproxy, Search requests that are part of the same
1246     session as an Init request that carries a
1247     <literal>VAL_PROXY</literal> otherInfo are also annotated with the
1248     same information.  The role of the <literal>virt_db</literal>
1249     filter is to rewrite this otherInfo packet dependent on the
1250     virtual database that the client wants to search.
1251    </para>
1252    <para>
1253     When Metaproxy receives a Z39.50 Init request from a client, it
1254     doesn't immediately forward that request to the back-end server.
1255     Why not?  Because it doesn't know <emphasis>which</emphasis>
1256     back-end server to forward it to until the client sends a Search
1257     request that specifies the database that it wants to search in.
1258     Instead, it just treasures the Init request up in its heart; and,
1259     later, the first time the client does a search on one of the
1260     specified virtual databases, a connection is forged to the
1261     appropriate server and the Init request is forwarded to it.  If,
1262     later in the session, the same client searches in a different
1263     virtual database, then a connection is forged to the server that
1264     hosts it, and the same cached Init request is forwarded there,
1265     too.
1266    </para>
1267    <para>
1268     All of this clever Init-delaying is done by the
1269     <literal>frontend_net</literal> filter.  The
1270     <literal>virt_db</literal> filter knows nothing about it; in
1271     fact, because the Init request that is received from the client
1272     doesn't get forwarded until a Search request is received, the
1273     <literal>virt_db</literal> filter (and the
1274     <literal>z3950_client</literal> filter behind it) doesn't even get
1275     invoked at Init time.  The <emphasis>only</emphasis> thing that a
1276     <literal>virt_db</literal> filter ever does is rewrite the
1277     <literal>VAL_PROXY</literal> otherInfo in the requests that pass
1278     through it.
1279    </para>
1280    <para>
1281     It is possible for a <literal>virt_db</literal> filter to contain
1282     multiple
1283     <literal>&lt;target&gt;</literal>
1284     elements.  What does this mean?  Only that the filter will add
1285     multiple <literal>VAL_PROXY</literal> otherInfo packets to the
1286     Search requests that pass through it.  That's because the virtual
1287     DB filter is dumb, and does exactly what it's told - no more, no
1288     less.
1289     If a Search request with multiple <literal>VAL_PROXY</literal>
1290     otherInfo packets reaches a <literal>z3950_client</literal>
1291     filter, this is an error.  That filter doesn't know how to deal
1292     with multiple targets, so it will either just pick one and search
1293     in it, or (better) fail with an error message.
1294    </para>
1295    <para>
1296     The <literal>multi</literal> filter comes to the rescue!  This is
1297     the only filter that knows how to deal with multiple
1298     <literal>VAL_PROXY</literal> otherInfo packets, and it does so by
1299     making multiple copies of the entire Search request: one for each
1300     <literal>VAL_PROXY</literal>.  Each of these new copies is then
1301     passed down through the remaining filters in the route.  (The
1302     copies are handled in parallel though the
1303     spawning of new threads.)  Since the copies each have only one
1304     <literal>VAL_PROXY</literal> otherInfo, they can be handled by the
1305     <literal>z3950_client</literal> filter, which happily deals with
1306     each one individually.  When the results of the individual
1307     searches come back up to the <literal>multi</literal> filter, it
1308     merges them into a single Search response, which is what
1309     eventually makes it back to the client.
1310    </para>
1311   </section>
1312
1313
1314   <section id="multidb.picture">
1315    <title>A picture is worth a thousand words (but only five hundred on 64-bit architectures)</title>
1316    <simpara>
1317     <inlinemediaobject>
1318      <imageobject>
1319       <imagedata fileref="multi.pdf" format="PDF" scale="50"/>
1320      </imageobject>
1321      <imageobject>
1322       <imagedata fileref="multi.png" format="PNG"/>
1323      </imageobject>
1324      <textobject>
1325       <!-- Fall back if none of the images can be used -->
1326       <phrase>
1327        [Here there should be a diagram showing the progress of
1328        packages through the filters during a simple virtual-database
1329        search and a multi-database search, but is seems that your
1330        toolchain has not been able to include the diagram in this
1331        document.  This is because of LaTeX suckage.  Time to move to
1332        OpenOffice.  Yes, really.]
1333       </phrase>
1334      </textobject>
1335 <!-- ### This used to work with an older version of DocBook
1336      <caption>
1337       <para>Caption: progress of packages through filters.</para>
1338      </caption>
1339 -->
1340     </inlinemediaobject>
1341    </simpara>
1342   </section>
1343  </chapter>
1344
1345
1346
1347  <chapter id="extensions">
1348   <title>Writing extensions for Metaproxy</title>
1349   <para>### To be written</para>
1350  </chapter>
1351
1352
1353
1354
1355  <chapter id="classes">
1356   <title>Classes in the Metaproxy source code</title>
1357
1358
1359   <section>
1360    <title>Introductory notes</title>
1361    <para>
1362     <emphasis>Stop!  Do not read this!</emphasis>
1363     You won't enjoy it at all.  You should just skip ahead to
1364     <link linkend="refguide">the reference guide</link>,
1365     which tells
1366     <!-- The remainder of this paragraph is lifted verbatim from
1367     Douglas Adams' _Hitch Hiker's Guide to the Galaxy_, chapter 8 -->
1368     you things you really need to know, like the fact that the
1369     fabulously beautiful planet Bethselamin is now so worried about
1370     the cumulative erosion by ten billion visiting tourists a year
1371     that any net imbalance between the amount you eat and the amount
1372     you excrete whilst on the planet is surgically removed from your
1373     bodyweight when you leave: so every time you go to the lavatory it
1374     is vitally important to get a receipt.
1375    </para>
1376    <para>
1377     This chapter contains documentation of the Metaproxy source code, and is
1378     of interest only to maintainers and developers.  If you need to
1379     change Metaproxy's behaviour or write a new filter, then you will most
1380     likely find this chapter helpful.  Otherwise it's a waste of your
1381     good time.  Seriously: go and watch a film or something.
1382     <citetitle>This is Spinal Tap</citetitle> is particularly good.
1383    </para>
1384    <para>
1385     Still here?  OK, let's continue.
1386    </para>
1387    <para>
1388     In general, classes seem to be named big-endianly, so that
1389     <literal>FactoryFilter</literal> is not a filter that filters
1390     factories, but a factory that produces filters; and
1391     <literal>FactoryStatic</literal> is a factory for the statically
1392     registered filters (as opposed to those that are dynamically
1393     loaded).
1394    </para>
1395   </section>
1396
1397   <section id="individual.classes">
1398    <title>Individual classes</title>
1399    <para>
1400     The classes making up the Metaproxy application are here listed by
1401     class-name, with the names of the source files that define them in
1402     parentheses.
1403    </para>
1404
1405    <section>
1406     <title><literal>mp::FactoryFilter</literal>
1407      (<filename>factory_filter.cpp</filename>)</title>
1408     <para>
1409      A factory class that exists primarily to provide the
1410      <literal>create()</literal> method, which takes the name of a
1411      filter class as its argument and returns a new filter of that
1412      type.  To enable this, the factory must first be populated by
1413      calling <literal>add_creator()</literal> for static filters (this
1414      is done by the <literal>FactoryStatic</literal> class, see below)
1415      and <literal>add_creator_dyn()</literal> for filters loaded
1416      dynamically.
1417     </para>
1418    </section>
1419
1420    <section>
1421     <title><literal>mp::FactoryStatic</literal>
1422      (<filename>factory_static.cpp</filename>)</title>
1423     <para>
1424      A subclass of <literal>FactoryFilter</literal> which is
1425      responsible for registering all the statically defined filter
1426      types.  It does this by knowing about all those filters'
1427      structures, which are listed in its constructor.  Merely
1428      instantiating this class registers all the static classes.  It is
1429      for the benefit of this class that <literal>struct
1430       metaproxy_1_filter_struct</literal> exists, and that all the filter
1431      classes provide a static object of that type.
1432     </para>
1433    </section>
1434
1435    <section>
1436     <title><literal>mp::filter::Base</literal>
1437      (<filename>filter.cpp</filename>)</title>
1438     <para>
1439      The virtual base class of all filters.  The filter API is, on the
1440      surface at least, extremely simple: two methods.
1441      <literal>configure()</literal> is passed a DOM tree representing
1442      that part of the configuration file that pertains to this filter
1443      instance, and is expected to walk that tree extracting relevant
1444      information.  And <literal>process()</literal> processes a
1445      package (see below).  That surface simplicitly is a bit
1446      misleading, as <literal>process()</literal> needs to know a lot
1447      about the <literal>Package</literal> class in order to do
1448      anything useful.
1449     </para>
1450    </section>
1451
1452    <section>
1453     <title><literal>mp::filter::AuthSimple</literal>,
1454      <literal>Backend_test</literal>, etc.
1455      (<filename>filter_auth_simple.cpp</filename>,
1456      <filename>filter_backend_test.cpp</filename>, etc.)</title>
1457     <para>
1458      Individual filters.  Each of these is implemented by a header and
1459      a source file, named <filename>filter_*.hpp</filename> and
1460      <filename>filter_*.cpp</filename> respectively.  All the header
1461      files should be pretty much identical, in that they declare the
1462      class, including a private <literal>Rep</literal> class and a
1463      member pointer to it, and the two public methods.  The only extra
1464      information in any filter header is additional private types and
1465      members (which should really all be in the <literal>Rep</literal>
1466      anyway) and private methods (which should also remain known only
1467      to the source file, but C++'s brain-damaged design requires this
1468      dirty laundry to be exhibited in public.  Thanks, Bjarne!)
1469     </para>
1470     <para>
1471      The source file for each filter needs to supply:
1472     </para>
1473     <itemizedlist>
1474      <listitem>
1475       <para>
1476        A definition of the private <literal>Rep</literal> class.
1477       </para>
1478      </listitem>
1479      <listitem>
1480       <para>
1481        Some boilerplate constructors and destructors.
1482       </para>
1483      </listitem>
1484      <listitem>
1485       <para>
1486        A <literal>configure()</literal> method that uses the
1487        appropriate XML fragment.
1488       </para>
1489      </listitem>
1490      <listitem>
1491       <para>
1492        Most important, the <literal>process()</literal> method that
1493        does all the actual work.
1494       </para>
1495      </listitem>
1496     </itemizedlist>
1497    </section>
1498
1499    <section>
1500     <title><literal>mp::Package</literal>
1501      (<filename>package.cpp</filename>)</title>
1502     <para>
1503      Represents a package on its way through the series of filters
1504      that make up a route.  This is essentially a Z39.50 or SRU APDU
1505      together with information about where it came from, which is
1506      modified as it passes through the various filters.
1507     </para>
1508    </section>
1509
1510    <section>
1511     <title><literal>mp::Pipe</literal>
1512      (<filename>pipe.cpp</filename>)</title>
1513     <para>
1514      This class provides a compatibility layer so that we have an IPC
1515      mechanism that works the same under Unix and Windows.  It's not
1516      particularly exciting.
1517     </para>
1518    </section>
1519
1520    <section>
1521     <title><literal>mp::RouterChain</literal>
1522      (<filename>router_chain.cpp</filename>)</title>
1523     <para>
1524      ### to be written
1525     </para>
1526    </section>
1527
1528    <section>
1529     <title><literal>mp::RouterFleXML</literal>
1530      (<filename>router_flexml.cpp</filename>)</title>
1531     <para>
1532      ### to be written
1533     </para>
1534    </section>
1535
1536    <section>
1537     <title><literal>mp::Session</literal>
1538      (<filename>session.cpp</filename>)</title>
1539     <para>
1540      ### to be written
1541     </para>
1542    </section>
1543
1544    <section>
1545     <title><literal>mp::ThreadPoolSocketObserver</literal>
1546      (<filename>thread_pool_observer.cpp</filename>)</title>
1547     <para>
1548      ### to be written
1549     </para>
1550    </section>
1551
1552    <section>
1553     <title><literal>mp::util</literal>
1554      (<filename>util.cpp</filename>)</title>
1555     <para>
1556      A namespace of various small utility functions and classes,
1557      collected together for convenience.  Most importantly, includes
1558      the <literal>mp::util::odr</literal> class, a wrapper for YAZ's
1559      ODR facilities.
1560     </para>
1561    </section>
1562
1563    <section>
1564     <title><literal>mp::xml</literal>
1565      (<filename>xmlutil.cpp</filename>)</title>
1566     <para>
1567      A namespace of various XML utility functions and classes,
1568      collected together for convenience.
1569     </para>
1570    </section>
1571   </section>
1572
1573
1574   <section id="other.source.files">
1575    <title>Other Source Files</title>
1576    <para>
1577     In addition to the Metaproxy source files that define the classes
1578     described above, there are a few additional files which are
1579     briefly described here:
1580    </para>
1581    <variablelist>
1582     <varlistentry>
1583      <term><literal>metaproxy_prog.cpp</literal></term>
1584      <listitem>
1585       <para>
1586        The main function of the <command>metaproxy</command> program.
1587       </para>
1588      </listitem>
1589     </varlistentry>
1590     <varlistentry>
1591      <term><literal>ex_router_flexml.cpp</literal></term>
1592      <listitem>
1593       <para>
1594        Identical to <literal>metaproxy_prog.cpp</literal>: it's not clear why.
1595       </para>
1596      </listitem>
1597     </varlistentry>
1598     <varlistentry>
1599      <term><literal>test_*.cpp</literal></term>
1600      <listitem>
1601       <para>
1602        Unit-tests for various modules.
1603       </para>
1604      </listitem>
1605     </varlistentry>
1606    </variablelist>
1607    <para>
1608     ### Still to be described:
1609     <literal>ex_filter_frontend_net.cpp</literal>,
1610     <literal>filter_dl.cpp</literal>,
1611     <literal>plainfile.cpp</literal>,
1612     <literal>tstdl.cpp</literal>.
1613    </para>
1614   </section>
1615  </chapter>
1616
1617
1618
1619  <chapter id="refguide">
1620   <title>Reference guide</title>
1621   <para>
1622    The material in this chapter is drawn directly from the individual
1623    manual entries.  In particular, the Metaproxy invocation section is
1624    available using <command>man metaproxy</command>, and the section
1625    on each individual filter is available using the name of the filter
1626    as the argument to the <command>man</command> command.
1627   </para>
1628
1629
1630   <section id="progref">
1631    <title>Metaproxy invocation</title>
1632    &progref;
1633   </section>
1634
1635
1636   <section id="filterref">
1637    <title>Reference guide to Metaproxy filters</title>
1638    &manref;
1639   </section>
1640  </chapter>
1641
1642
1643
1644  <!-- Keep this comment at the end of the file
1645  Local variables:
1646  mode: sgml
1647  sgml-omittag:t
1648  sgml-shorttag:t
1649  sgml-minimize-attributes:nil
1650  sgml-always-quote-attributes:t
1651  sgml-indent-step:1
1652  sgml-indent-data:t
1653  sgml-parent-document: "main.xml"
1654  sgml-local-catalogs: nil
1655  sgml-namecase-general:t
1656  End:
1657  -->