Convert multi.svg to multi.pdf and include it (kernel compile unnecessary)
[metaproxy-moved-to-github.git] / doc / book.xml
1 <!-- $Id: book.xml,v 1.26 2006-04-27 16:38:13 adam 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 used Metaproxy with Boost 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</title>
245    <para>
246     ### To be written
247    </para>
248    <para>
249     (Of course, since Debian is a Unix system, the instructions in the
250     previous section can be used.)
251    </para>
252    </section>
253
254   <section id="installation.windows">
255    <title>Installation on Windows</title>
256    <para>
257     Compilation of Metaproxy can be done using
258     Microsoft <ulink url="&url.vstudio;">Visual Studio</ulink>.
259     We know Version 2003 works. We expect Version 2005 to
260     work as well.
261    </para>
262    <section id="installation.windows.boost">
263     <title>Boost</title>
264     <para>
265      Get Boost from its <ulink url="&url.boost;">home page</ulink>.
266      You also need Boost Jam (an alternative to make).
267      That's also available from this
268      home page. The files download are called something like:
269      <literal>boost_1_33-1.exe</literal>
270      and
271      <literal>boost-jam-3.1.12-1-ntx86.zip</literal>.
272      Unpack Boost Jam first. Put <literal>bjam.exe</literal>
273      in your system path. Make a command prompt and ensure
274      it can be found automatically. If not check the PATH.
275      The Boost .exe is a self-extracting exe with
276      complete source for Boost. Compile that source with
277      Boost Jam (An alternative to Make).
278      The compilation takes a while.
279      By default, the Boost build process puts the resulting
280      libraries + header files in
281      <literal>\boost\lib</literal>, <literal>\boost\include</literal>.
282     </para>
283     <para>
284      For more informatation about installing Boost refer to the
285      <ulink url="&url.boost.getting.started;">getting started</ulink>
286      pages.
287     </para>
288    </section>
289
290    <section id="installation.windows.libxslt">
291     <title>Libxslt</title>
292     <para>
293      <ulink url="&url.libxslt;">Libxslt</ulink> can be downloaded
294      for Windows from
295      <ulink url="&url.libxml2.download.win32;">here</ulink>.
296     </para>
297     <para>
298      Libxslt has other dependencies, but thes can all be downloaded
299      from the same site. Get the following:
300      iconv, zlib, libxml2, libxslt.
301     </para>
302    </section>
303
304    <section id="installation.windows.yaz">
305     <title>YAZ</title>
306     <para>
307      <ulink url="&url.yaz;">YAZ</ulink> can be downloaded
308      for Windows from
309      <ulink url="&url.yaz.download.win32;">here</ulink>.
310     </para>
311    </section>
312
313    <section id="installation.windows.yazplusplus">
314     <title>YAZ++</title>
315     <para>
316      Get <ulink url="&url.yazplusplus;">YAZ++</ulink> as well.
317      Version 1.0 or later is required. For now get it from
318      Index Data's
319      <ulink url="&url.snapshot.download;">Snapshot area</ulink>.
320     </para>
321     <para>
322      YAZ++ includes NMAKE makefiles, similar to those found in the
323      YAZ package.
324     </para>
325    </section>
326
327    <section id="installation.windows.metaproxy">
328     <title>Metaproxy</title>
329     <para>
330      Metaproxy is shipped with NMAKE makfiles as well - similar
331      to those found in the YAZ++/YAZ packages. Adjust this Makefile
332      to point to the proper locations of Boost, Libxslt, Libxml2,
333      zlib, iconv, yaz and yazpp.
334     </para>
335     <para>
336      After succesful compilation you'll find
337      <literal>metaproxy.exe</literal> in the
338      <literal>bin</literal> directory.
339     </para>
340    </section>
341
342   </section>
343  </chapter>
344  
345  <chapter id="architecture">
346   <title>The Metaproxy Architecture</title>
347   <para>
348    The Metaproxy architecture is based on three concepts:
349    the <emphasis>package</emphasis>,
350    the <emphasis>route</emphasis>
351    and the <emphasis>filter</emphasis>.
352   </para>
353   <variablelist>
354    <varlistentry>
355     <term>Packages</term>
356     <listitem>
357      <para>
358       A package is request or response, encoded in some protocol,
359       issued by a client, making its way through Metaproxy, send to or
360       received from a server, or sent back to the client.
361      </para>
362      <para>
363       The core of a package is the protocol unit - for example, a
364       Z39.50 Init Request or Search Response, or an SRU searchRetrieve
365       URL or Explain Response.  In addition to this core, a package
366       also carries some extra information added and used by Metaproxy
367       itself.
368      </para>
369      <para>
370       In general, packages are doctored as they pass through
371       Metaproxy.  For example, when the proxy performs authentication
372       and authorisation on a Z39.50 Init request, it removes the
373       authentication credentials from the package so that they are not
374       passed onto the back-end server; and when search-response
375       packages are obtained from multiple servers, they are merged
376       into a single unified package that makes its way back to the
377       client.
378      </para>
379     </listitem>
380    </varlistentry>
381    <varlistentry>
382     <term>Routes</term>
383     <listitem>
384      <para>
385       Packages make their way through routes, which can be thought of
386       as programs that operate on the package data-type.  Each
387       incoming package initially makes its way through a default
388       route, but may be switched to a different route based on various
389       considerations.  Routes are made up of sequences of filters (see
390       below).
391      </para>
392     </listitem>
393    </varlistentry>
394    <varlistentry>
395     <term>Filters</term>
396     <listitem>
397      <para>
398       Filters provide the individual instructions within a route, and
399       effect the necessary transformations on packages.  A particular
400       configuration of Metaproxy is essentially a set of filters,
401       described by configuration details and arranged in order in one
402       or more routes.  There are many kinds of filter - about a dozen
403       at the time of writing with more appearing all the time - each
404       performing a specific function and configured by different
405       information.
406      </para>
407      <para>
408       The word ``filter'' is sometimes used rather loosely, in two
409       different ways: it may be used to mean a particular
410       <emphasis>type</emphasis> of filter, as when we speak of ``the
411       auth_simplefilter'' or ``the multi filter''; or it may be used
412       to be a specific <emphasis>instance</emphasis> of a filter
413       within a Metaproxy configuration.  For example, a single
414       configuration will often contain multiple instances of the
415       <literal>z3950_client</literal> filter.  In
416       operational terms, of these is a separate filter.  In practice,
417       context always make it clear which sense of the word ``filter''
418       is being used.
419      </para>
420      <para>
421       Extensibility of Metaproxy is primarily through the creation of
422       plugins that provide new filters.  The filter API is small and
423       conceptually simple, but there are many details to master.  See
424       the section below on
425       <link linkend="extensions">extensions</link>.
426      </para>
427     </listitem>
428    </varlistentry>
429   </variablelist>
430   <para>
431    Since packages are created and handled by the system itself, and
432    routes are conceptually simple, most of the remainder of this
433    document concentrates on filters.  After a brief overview of the
434    filter types follows, along with some thoughts on possible future
435    directions.
436   </para>
437  </chapter>
438
439
440
441  <chapter id="filters">
442   <title>Filters</title>
443   
444   
445   <section>
446    <title>Introductory notes</title>
447    <para>
448     It's useful to think of Metaproxy as an interpreter providing a small
449     number of primitives and operations, but operating on a very
450     complex data type, namely the ``package''.
451    </para>
452    <para>
453     A package represents a Z39.50 or SRU/W request (whether for Init,
454     Search, Scan, etc.)  together with information about where it came
455     from.  Packages are created by front-end filters such as
456     <literal>frontend_net</literal> (see below), which reads them from
457     the network; other front-end filters are possible.  They then pass
458     along a route consisting of a sequence of filters, each of which
459     transforms the package and may also have side-effects such as
460     generating logging.  Eventually, the route will yield a response,
461     which is sent back to the origin.
462    </para>
463    <para>
464     There are many kinds of filter: some that are defined statically
465     as part of Metaproxy, and others may be provided by third parties
466     and dynamically loaded.  They all conform to the same simple API
467     of essentially two methods: <function>configure()</function> is
468     called at startup time, and is passed a DOM tree representing that
469     part of the configuration file that pertains to this filter
470     instance: it is expected to walk that tree extracting relevant
471     information; and <function>process()</function> is called every
472     time the filter has to processes a package.
473    </para>
474    <para>
475     While all filters provide the same API, there are different modes
476     of functionality.  Some filters are sources: they create
477     packages
478     (<literal>frontend_net</literal>);
479     others are sinks: they consume packages and return a result
480     (<literal>z3950_client</literal>,
481     <literal>backend_test</literal>,
482     <literal>http_file</literal>);
483     the others are true filters, that read, process and pass on the
484     packages they are fed
485     (<literal>auth_simple</literal>,
486     <literal>log</literal>,
487     <literal>multi</literal>,
488     <literal>query_rewrite</literal>,
489     <literal>session_shared</literal>,
490     <literal>template</literal>,
491     <literal>virt_db</literal>).
492    </para>
493  </section>
494   
495   
496   <section id="overview.filter.types">
497    <title>Overview of filter types</title>
498    <para>
499     We now briefly consider each of the types of filter supported by
500     the core Metaproxy binary.  This overview is intended to give a
501     flavour of the available functionality; more detailed information
502     about each type of filter is included below in
503     <link linkend="filterref"
504           >the reference guide to Metaproxy filters</link>.
505    </para>
506    <para>
507     The filters are here named by the string that is used as the
508     <literal>type</literal> attribute of a
509     <literal>&lt;filter&gt;</literal> element in the configuration
510     file to request them, with the name of the class that implements
511     them in parentheses.  (The classname is not needed for normal
512     configuration and use of Metaproxy; it is useful only to
513     developers.)
514    </para>
515    <para>
516     The filters are here listed in alphabetical order:
517    </para>
518    
519    <section>
520     <title><literal>auth_simple</literal>
521      (mp::filter::AuthSimple)</title>
522     <para>
523      Simple authentication and authorisation.  The configuration
524      specifies the name of a file that is the user register, which
525      lists <varname>username</varname>:<varname>password</varname>
526      pairs, one per line, colon separated. When a session begins, it
527      is rejected unless username and passsword are supplied, and match
528      a pair in the register.  The configuration file may also specific
529      the name of another file that is the target register: this lists
530      lists <varname>username</varname>:<varname>dbname</varname>,<varname>dbname</varname>...
531      sets, one per line, with multiple database names separated by
532      commas.  When a search is processed, it is rejected unless the
533      database to be searched is one of those listed as available to
534      the user.
535     </para>
536    </section>
537    
538    <section>
539     <title><literal>backend_test</literal>
540     (mp::filter::Backend_test)</title>
541     <para>
542      A sink that provides dummy responses in the manner of the
543      <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
544      for testing.  Seriously, you don't need this.  Pretend you didn't
545      even read this section.
546     </para>
547    </section>
548    
549    <section>
550     <title><literal>frontend_net</literal>
551      (mp::filter::FrontendNet)</title>
552     <para>
553      A source that accepts Z39.50 connections from a port
554      specified in the configuration, reads protocol units, and
555      feeds them into the next filter in the route.  When the result is
556      revceived, it is returned to the original origin.
557     </para>
558    </section>
559
560    <section>
561     <title><literal>http_file</literal>
562      (mp::filter::HttpFile)</title>
563     <para>
564      A sink that returns the contents of files from the local
565      filesystem in response to HTTP requests.  (Yes, Virginia, this
566      does mean that Metaproxy is also a Web-server in its spare time.  So
567      far it does not contain either an email-reader or a Lisp
568      interpreter, but that day is surely coming.)
569     </para>
570    </section>
571    
572    <section>
573     <title><literal>log</literal>
574      (mp::filter::Log)</title>
575     <para>
576      Writes logging information to standard output, and passes on
577      the package unchanged.
578    </para>
579    </section>
580    
581    <section>
582    <title><literal>multi</literal>
583      (mp::filter::Multi)</title>
584     <para>
585      Performs multi-database searching.
586      See
587      <link linkend="multidb">the extended discussion</link>
588      of virtual databases and multi-database searching below.
589     </para>
590    </section>
591    
592    <section>
593    <title><literal>query_rewrite</literal>
594      (mp::filter::QueryRewrite)</title>
595     <para>
596      Rewrites Z39.50 Type-1 and Type-101 (``RPN'') queries by a
597      three-step process: the query is transliterated from Z39.50
598      packet structures into an XML representation; that XML
599      representation is transformed by an XSLT stylesheet; and the
600      resulting XML is transliterated back into the Z39.50 packet
601      structure.
602     </para>
603    </section>
604    
605    <section>
606     <title><literal>session_shared</literal>
607      (mp::filter::SessionShared)</title>
608     <para>
609      When this is finished, it will implement global sharing of
610      result sets (i.e. between threads and therefore between
611      clients), yielding performance improvements especially when
612      incoming requests are from a stateless environment such as a
613      web-server, in which the client process representing a session
614      might be any one of many.  However:
615     </para>
616     <warning>
617      <para>
618       This filter is not yet completed.
619      </para>
620     </warning>
621    </section>
622    
623    <section>
624     <title><literal>template</literal>
625      (mp::filter::Template)</title>
626     <para>
627      Does nothing at all, merely passing the packet on.  (Maybe it
628      should be called <literal>nop</literal> or
629      <literal>passthrough</literal>?)  This exists not to be used, but
630      to be copied - to become the skeleton of new filters as they are
631      written.  As with <literal>backend_test</literal>, this is not
632      intended for civilians.
633     </para>
634    </section>
635    
636    <section>
637     <title><literal>virt_db</literal>
638      (mp::filter::Virt_db)</title>
639     <para>
640      Performs virtual database selection: based on the name of the
641      database in the search request, a server is selected, and its
642      address added to the request in a <literal>VAL_PROXY</literal>
643      otherInfo packet.  It will subsequently be used by a
644      <literal>z3950_client</literal> filter.
645      See
646      <link linkend="multidb">the extended discussion</link>
647      of virtual databases and multi-database searching below.
648     </para>
649    </section>
650    
651    <section>
652     <title><literal>z3950_client</literal>
653      (mp::filter::Z3950Client)</title>
654     <para>
655      Performs Z39.50 searching and retrieval by proxying the
656      packages that are passed to it.  Init requests are sent to the
657      address specified in the <literal>VAL_PROXY</literal> otherInfo
658      attached to the request: this may have been specified by client,
659      or generated by a <literal>virt_db</literal> filter earlier in
660      the route.  Subsequent requests are sent to the same address,
661      which is remembered at Init time in a Session object.
662     </para>
663   </section>
664   </section>
665   
666   
667   <section id="future.directions">
668    <title>Future directions</title>
669   <para>
670     Some other filters that do not yet exist, but which would be
671     useful, are briefly described.  These may be added in future
672     releases (or may be created by third parties, as loadable
673     modules).
674    </para>
675
676    <variablelist>
677     <varlistentry>
678      <term><literal>frontend_cli</literal> (source)</term>
679     <listitem>
680       <para>
681        Command-line interface for generating requests.
682       </para>
683      </listitem>
684     </varlistentry>
685     <varlistentry>
686      <term><literal>frontend_sru</literal> (source)</term>
687      <listitem>
688       <para>
689        Receive SRU (and perhaps SRW) requests.
690      </para>
691      </listitem>
692     </varlistentry>
693     <varlistentry>
694      <term><literal>sru2z3950</literal> (filter)</term>
695      <listitem>
696       <para>
697        Translate SRU requests into Z39.50 requests.
698      </para>
699      </listitem>
700     </varlistentry>
701     <varlistentry>
702      <term><literal>sru_client</literal> (sink)</term>
703      <listitem>
704       <para>
705        SRU searching and retrieval.
706       </para>
707      </listitem>
708     </varlistentry>
709     <varlistentry>
710      <term><literal>srw_client</literal> (sink)</term>
711      <listitem>
712       <para>
713        SRW searching and retrieval.
714       </para>
715      </listitem>
716     </varlistentry>
717     <varlistentry>
718      <term><literal>opensearch_client</literal> (sink)</term>
719      <listitem>
720       <para>
721        A9 OpenSearch searching and retrieval.
722       </para>
723      </listitem>
724     </varlistentry>
725    </variablelist>
726   </section>
727  </chapter>
728  
729  
730  
731  <chapter id="configuration">
732   <title>Configuration: the Metaproxy configuration file format</title>
733   
734   
735   <section>
736    <title>Introductory notes</title>
737    <para>
738     If Metaproxy is an interpreter providing operations on packages, then
739     its configuration file can be thought of as a program for that
740     interpreter.  Configuration is by means of a single file, the name
741     of which is supplied as the sole command-line argument to the
742     <command>metaproxy</command> program.  (See
743     <link linkend="progref">the reference guide</link>
744     below for more information on invoking Metaproxy.)
745    </para>
746    <para>
747     The configuration files are written in XML.  (But that's just an
748     implementation detail - they could just as well have been written
749     in YAML or Lisp-like S-expressions, or in a custom syntax.)
750    </para>
751    <para>
752     Since XML has been chosen, an XML schema,
753     <filename>config.xsd</filename>, is provided for validating
754     configuration files.  This file is supplied in the
755     <filename>etc</filename> directory of the Metaproxy distribution.  It
756     can be used by (among other tools) the <command>xmllint</command>
757     program supplied as part of the <literal>libxml2</literal>
758     distribution:
759    </para>
760    <screen>
761     xmllint --noout --schema etc/config.xsd my-config-file.xml
762    </screen>
763    <para>
764     (A recent version of <literal>libxml2</literal> is required, as
765     support for XML Schemas is a relatively recent addition.)
766    </para>
767   </section>
768   
769   <section id="overview.xml.structure">
770    <title>Overview of XML structure</title>
771    <para>
772     All elements and attributes are in the namespace
773     <ulink url="http://indexdata.dk/yp2/config/1"/>.
774      This is most easily achieved by setting the default namespace on
775      the top-level element, as here:
776    </para>
777    <screen>
778     &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
779    </screen>
780    <para>
781     The top-level element is &lt;yp2&gt;.  This contains a
782     &lt;start&gt; element, a &lt;filters&gt; element and a
783     &lt;routes&gt; element, in that order.  &lt;filters&gt; is
784     optional; the other two are mandatory.  All three are
785     non-repeatable.
786    </para>
787   <para>
788     The &lt;start&gt; element is empty, but carries a
789     <literal>route</literal> attribute, whose value is the name of
790     route at which to start running - analogous to the name of the
791     start production in a formal grammar.
792    </para>
793   <para>
794     If present, &lt;filters&gt; contains zero or more &lt;filter&gt;
795     elements.  Each filter carries a <literal>type</literal> attribute
796     which specifies what kind of filter is being defined
797     (<literal>frontend_net</literal>, <literal>log</literal>, etc.)
798     and contain various elements that provide suitable configuration
799     for a filter of its type.  The filter-specific elements are
800     described in
801     <link linkend="filterref">the reference guide below</link>.
802     Filters defined in this part of the file must carry an
803     <literal>id</literal> attribute so that they can be referenced
804     from elsewhere.
805    </para>
806    <para>
807     &lt;routes&gt; contains one or more &lt;route&gt; elements, each
808     of which must carry an <literal>id</literal> element.  One of the
809     routes must have the ID value that was specified as the start
810     route in the &lt;start&gt; element's <literal>route</literal>
811     attribute.  Each route contains zero or more &lt;filter&gt;
812     elements.  These are of two types.  They may be empty, but carry a
813     <literal>refid</literal> attribute whose value is the same as the
814     <literal>id</literal> of a filter previously defined in the
815     &lt;filters&gt; section.  Alternatively, a route within a filter
816     may omit the <literal>refid</literal> attribute, but contain
817     configuration elements similar to those used for filters defined
818     in the &lt;filters&gt; section.  (In other words, each filter in a
819     route may be included either by reference or by physical
820     inclusion.)
821    </para>
822   </section>
823
824
825   <section id="example.configuration">
826    <title>An example configuration</title>
827    <para>
828     The following is a small, but complete, Metaproxy configuration
829     file (included in the distribution as
830     <literal>metaproxy/etc/config0.xml</literal>).
831     This file defines a very simple configuration that simply proxies
832     to whatever back-end server the client requests, but logs each
833     request and response.  This can be useful for debugging complex
834     client-server dialogues.
835    </para>
836    <screen><![CDATA[<?xml version="1.0"?>
837 <yp2 xmlns="http://indexdata.dk/yp2/config/1">
838   <start route="start"/>
839   <filters>
840     <filter id="frontend" type="frontend_net">
841       <port>@:9000</port>
842     </filter>
843     <filter id="backend" type="z3950_client">
844     </filter>
845   </filters>
846   <routes>  
847     <route id="start">
848       <filter refid="frontend"/>
849       <filter type="log"/>
850       <filter refid="backend"/>
851     </route>
852   </routes>
853 </yp2>
854 ]]></screen>
855    <para>
856     It works by defining a single route, called
857     <literal>start</literal>, which consists of a sequence of three
858     filters.  The first and last of these are included by reference:
859     their <literal>&lt;filter&gt;</literal> elements have
860     <literal>refid</literal> attributes that refer to filters defined
861     within the prior <literal>&lt;filters&gt;</literal> section.  The
862     middle filter is included inline in the route.
863    </para>
864    <para>
865     The three filters in the route are as follows: first, a
866     <literal>frontend_net</literal> filter accepts Z39.50 requests
867     from any host on port 9000; then these requests are passed through
868     a <literal>log</literal> filter that emits a message for each
869     request; they are then fed into a <literal>z3950_client</literal>
870     filter, which forwards the requests to the client-specified
871     back-end Z39.509 server.  When the response arrives, it is handed
872     back to the <literal>log</literal> filter, which emits another
873     message; and then to the front-end filter, which returns the
874     response to the client.
875    </para>
876   </section>
877  </chapter>
878
879
880
881  <chapter id="multidb">
882   <title>Virtual databases and multi-database searching</title>
883
884
885   <section>
886    <title>Introductory notes</title>
887    <para>
888     Two of Metaproxy's filters are concerned with multiple-database
889     operations.  Of these, <literal>virt_db</literal> can work alone
890     to control the routing of searches to one of a number of servers,
891     while <literal>multi</literal> can work together with
892     <literal>virt_db</literal> to perform multi-database searching, merging
893     the results into a unified result-set - ``metasearch in a box''.
894    </para>
895    <para>
896     The interaction between
897     these two filters is necessarily complex: it reflects the real,
898     irreducible complexity of multi-database searching in a protocol such
899     as Z39.50 that separates initialisation from searching, and in
900     which the database to be searched is not known at initialisation
901     time.
902    </para>
903    <para>
904     It's possible to use these filters without understanding the
905     details of their functioning and the interaction between them; the
906     next two sections of this chapter are ``HOWTO'' guides for doing
907     just that.  However, debugging complex configurations will require
908     a deeper understanding, which the last two sections of this
909     chapters attempt to provide.
910    </para>
911   </section>
912
913
914   <section id="multidb.virt_db">
915    <title>Virtual databases with the <literal>virt_db</literal> filter</title>
916    <para>
917     Working alone, the purpose of the
918     <literal>virt_db</literal>
919     filter is to route search requests to one of a selection of
920     back-end databases.  In this way, a single Z39.50 endpoint
921     (running Metaproxy) can provide access to several different
922     underlying services, including those that would otherwise be
923     inaccessible due to firewalls.  In many useful configurations, the
924     back-end databases are local to the Metaproxy installation, but
925     the software does not enforce this, and any valid Z39.50 servers
926     may be used as back-ends.
927    </para>
928    <para>
929     For example, a <literal>virt_db</literal>
930     filter could be set up so that searches in the virtual database
931     ``lc'' are forwarded to the Library of Congress bibliographic
932     catalogue server, and searches in the virtual database ``marc''
933     are forwarded to the toy database of MARC records that Index Data
934     hosts for testing purposes.  A <literal>virt_db</literal>
935     configuration to make this switch would look like this:
936    </para>
937    <screen><![CDATA[<filter type="virt_db">
938   <virtual>
939     <database>lc</database>
940     <target>z3950.loc.gov:7090/voyager</target>
941   </virtual>
942   <virtual>
943     <database>marc</database>
944     <target>indexdata.dk/marc</target>
945   </virtual>
946 </filter>]]></screen>
947    <para>
948     As well as being useful in it own right, this filter also provides
949     the foundation for multi-database searching.
950    </para>
951   </section>
952
953
954   <section id="multidb.multi">
955    <title>Multi-database search with the <literal>multi</literal> filter</title>
956    <para>
957     To arrange for Metaproxy to broadcast searches to multiple back-end
958     servers, the configuration needs to include two components: a
959     <literal>virt_db</literal>
960     filter that specifies multiple
961     <literal>&lt;target&gt;</literal>
962     elements, and a subsequent
963     <literal>multi</literal>
964     filter.  Here, for example, is a complete configuration that
965     broadcasts searches to both the Library of Congress catalogue and
966     Index Data's tiny testing database of MARC records:
967    </para>
968    <screen><![CDATA[<?xml version="1.0"?>
969 <yp2 xmlns="http://indexdata.dk/yp2/config/1">
970   <start route="start"/>
971   <routes>
972     <route id="start">
973       <filter type="frontend_net">
974         <threads>10</threads>
975         <port>@:9000</port>
976       </filter>
977       <filter type="virt_db">
978         <virtual>
979           <database>lc</database>
980           <target>z3950.loc.gov:7090/voyager</target>
981         </virtual>
982         <virtual>
983           <database>marc</database>
984           <target>indexdata.dk/marc</target>
985         </virtual>
986         <virtual>
987           <database>all</database>
988           <target>z3950.loc.gov:7090/voyager</target>
989           <target>indexdata.dk/marc</target>
990         </virtual>
991       </filter>
992       <filter type="multi"/>
993       <filter type="z3950_client">
994         <timeout>30</timeout>
995       </filter>
996     </route>
997   </routes>
998 </yp2>]]></screen>
999    <para>
1000     (Using a
1001     <literal>virt_db</literal>
1002     filter that specifies multiple
1003     <literal>&lt;target&gt;</literal>
1004     elements but without a subsequent
1005     <literal>multi</literal>
1006     filter yields surprising and undesirable results, as will be
1007     described below.  Don't do that.)
1008    </para>
1009    <para>
1010     Metaproxy can be invoked with this configuration as follows:
1011    </para>
1012    <screen>../src/metaproxy --config config-simple-multi.xml</screen>
1013    <para>
1014     And thereafter, Z39.50 clients can connect to the running server
1015     (on port 9000, as specified in the configuration) and search in
1016     any of the databases
1017     <literal>lc</literal> (the Library of Congress catalogue),
1018     <literal>marc</literal> (Index Data's test database of MARC records)
1019     or
1020     <literal>all</literal> (both of these).  As an example, a session
1021     using the YAZ command-line client <literal>yaz-client</literal> is
1022     here included (edited for brevity and clarity):
1023    </para>
1024    <screen><![CDATA[$ yaz-client @:9000
1025 Connecting...OK.
1026 Z> base lc
1027 Z> find computer
1028 Search was a success.
1029 Number of hits: 10000, setno 1
1030 Elapsed: 5.521070
1031 Z> base marc
1032 Z> find computer
1033 Search was a success.
1034 Number of hits: 10, setno 3
1035 Elapsed: 0.060187
1036 Z> base all
1037 Z> find computer
1038 Search was a success.
1039 Number of hits: 10010, setno 4
1040 Elapsed: 2.237648
1041 Z> show 1
1042 [marc]Record type: USmarc
1043 001    11224466
1044 003 DLC
1045 005 00000000000000.0
1046 008 910710c19910701nju           00010 eng
1047 010    $a 11224466
1048 040    $a DLC $c DLC
1049 050 00 $a 123-xyz
1050 100 10 $a Jack Collins
1051 245 10 $a How to program a computer
1052 260 1  $a Penguin
1053 263    $a 8710
1054 300    $a p. cm.
1055 Elapsed: 0.119612
1056 Z> show 2
1057 [VOYAGER]Record type: USmarc
1058 001 13339105
1059 005 20041229102447.0
1060 008 030910s2004    caua          000 0 eng
1061 035    $a (DLC)  2003112666
1062 906    $a 7 $b cbc $c orignew $d 4 $e epcn $f 20 $g y-gencatlg
1063 925 0  $a acquire $b 1 shelf copy $x policy default
1064 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.
1065 010    $a   2003112666
1066 020    $a 0761542892
1067 040    $a DLC $c DLC $d DLC
1068 050 00 $a MLCM 2004/03312 (G)
1069 245 10 $a 007, everything or nothing : $b Prima's official strategy guide / $c created by Kaizen Media Group.
1070 246 3  $a Double-O-seven, everything or nothing
1071 246 30 $a Prima's official strategy guide
1072 260    $a Roseville, CA : $b Prima Games, $c c2004.
1073 300    $a 161 p. : $b col. ill. ; $c 28 cm.
1074 500    $a "Platforms: Nintendo GameCube, Macintosh, PC, PlayStation 2 computer entertainment system, Xbox"--P. [4] of cover.
1075 650  0 $a Video games.
1076 710 2  $a Kaizen Media Group.
1077 856 42 $3 Publisher description $u http://www.loc.gov/catdir/description/random052/2003112666.html
1078 Elapsed: 0.150623
1079 Z>
1080 ]]></screen>
1081    <para>
1082     As can be seen, the first record in the result set is from the
1083     Index Data test database, and the second from the Library of
1084     Congress database.  The result-set continues alternating records
1085     round-robin style until the point where one of the databases'
1086     records are exhausted.
1087    </para>
1088    <para>
1089     This example uses only two back-end databases; more may be used.
1090     There is no limitation imposed on the number of databases that may
1091     be metasearched in this way: issues of resource usage and
1092     administrative complexity dictate the practical limits.
1093    </para>
1094   </section>
1095
1096
1097   <section id="multidb.what">
1098    <title>What's going on?</title>
1099    <warning>
1100     <title>Lark's vomit</title>
1101     <para>
1102      This section goes into a level of technical detail that is
1103      probably not necessary in order to configure and use Metaproxy.
1104      It is provided only for those who like to know how things work.
1105      You should feel free to skip on to the next section if this one
1106      doesn't seem like fun.
1107     </para>
1108    </warning>
1109    <para>
1110     Hold on tight - this may get a little hairy.
1111    </para>
1112    <para>
1113     In the general course of things, a Z39.50 Init request may carry
1114     with it an otherInfo packet of type <literal>VAL_PROXY</literal>,
1115     whose value indicates the address of a Z39.50 server to which the
1116     ultimate connection is to be made.  (This otherInfo packet is
1117     supported by YAZ-based Z39.50 clients and servers, but has not yet
1118     been ratified by the Maintenance Agency and so is not widely used
1119     in non-Index Data software.  We're working on it.)
1120     The <literal>VAL_PROXY</literal> packet functions
1121     analogously to the absoluteURI-style Request-URI used with the GET
1122     method when a web browser asks a proxy to forward its request: see
1123     the
1124     <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2"
1125            >Request-URI</ulink>
1126     section of
1127     <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616.html"
1128            >the HTTP 1.1 specification</ulink>.
1129    </para>
1130    <para>
1131     The role of the <literal>virt_db</literal> filter is to rewrite
1132     this otherInfo packet dependent on the virtual database that the
1133     client wants to search.  
1134    </para>
1135    <para>
1136     When Metaproxy receives a Z39.50 Init request from a client, it
1137     doesn't immediately forward that request to the back-end server.
1138     Why not?  Because it doesn't know <emphasis>which</emphasis>
1139     back-end server to forward it to until the client sends a search
1140     request that specifies the database that it wants to search in.
1141     Instead, it just treasures the Init request up in its heart; and,
1142     later, the first time the client does a search on one of the
1143     specified virtual databases, a connection is forged to the
1144     appropriate server and the Init request is forwarded to it.  If,
1145     later in the session, the same client searches in a different
1146     virtual database, then a connection is forged to the server that
1147     hosts it, and the same cached Init request is forwarded there,
1148     too.
1149    </para>
1150    <para>
1151     All of this clever Init-delaying is done by the
1152     <literal>frontend_net</literal> filter.  The
1153     <literal>virt_db</literal> filter knows nothing about it; in
1154     fact, because the Init request that is received from the client
1155     doesn't get forwarded until a Search request is received, the
1156     <literal>virt_db</literal> filter (and the
1157     <literal>z3950_client</literal> filter behind it) doesn't even get
1158     invoked at Init time.  The <emphasis>only</emphasis> thing that a
1159     <literal>virt_db</literal> filter ever does is rewrite the
1160     <literal>VAL_PROXY</literal> otherInfo in the requests that pass
1161     through it.
1162    </para>
1163    <para>
1164     ### Describe the use of multiple <literal>VAL_PROXY</literal>
1165     otherInfos, added by <literal>virt_db</literal> and used by
1166     <literal>multi</literal>.
1167    </para>
1168   </section>
1169
1170
1171   <section id="multidb.picture">
1172    <title>A picture is worth a thousand words (but only five hundred on 64-bit architectures)</title>
1173    <simpara>
1174     <inlinemediaobject>
1175      <imageobject>
1176       <imagedata fileref="multi.pdf" format="PDF" scale="50"/>
1177      </imageobject>
1178      <imageobject>
1179       <imagedata fileref="multi.png" format="PNG"/>
1180      </imageobject>
1181      <textobject>
1182       <!-- Fall back if none of the images can be used -->
1183       <phrase>
1184        [Here there should be a diagram showing the progress of
1185        packages through the filters during a simple virtual-database
1186        search and a multi-database search, but is seems that your
1187        toolchain has not been able to include the diagram in this
1188        document.  This is because of LaTeX suckage.  Time to move to
1189        OpenOffice.  Yes, really.]
1190       </phrase>
1191      </textobject>
1192 <!-- ### This used to work with an older version of DocBook
1193      <caption>
1194       <para>Caption: progress of packages through filters.</para>
1195      </caption>
1196 -->
1197     </inlinemediaobject>
1198    </simpara>
1199   </section>
1200  </chapter>
1201
1202
1203
1204  <chapter id="extensions">
1205   <title>Writing extensions for Metaproxy</title>
1206   <para>### To be written</para>
1207  </chapter>
1208
1209
1210
1211
1212  <chapter id="classes">
1213   <title>Classes in the Metaproxy source code</title>
1214
1215
1216   <section>
1217    <title>Introductory notes</title>
1218    <para>
1219     <emphasis>Stop!  Do not read this!</emphasis>
1220     You won't enjoy it at all.  You should just skip ahead to
1221     <link linkend="refguide">the reference guide</link>,
1222     which tells
1223     <!-- The remainder of this paragraph is lifted verbatim from
1224     Douglas Adams' _Hitch Hiker's Guide to the Galaxy_, chapter 8 -->
1225     you things you really need to know, like the fact that the
1226     fabulously beautiful planet Bethselamin is now so worried about
1227     the cumulative erosion by ten billion visiting tourists a year
1228     that any net imbalance between the amount you eat and the amount
1229     you excrete whilst on the planet is surgically removed from your
1230     bodyweight when you leave: so every time you go to the lavatory it
1231     is vitally important to get a receipt.
1232    </para>
1233    <para>
1234     This chapter contains documentation of the Metaproxy source code, and is
1235     of interest only to maintainers and developers.  If you need to
1236     change Metaproxy's behaviour or write a new filter, then you will most
1237     likely find this chapter helpful.  Otherwise it's a waste of your
1238     good time.  Seriously: go and watch a film or something.
1239     <citetitle>This is Spinal Tap</citetitle> is particularly good.
1240    </para>
1241    <para>
1242     Still here?  OK, let's continue.
1243    </para>
1244    <para>
1245     In general, classes seem to be named big-endianly, so that
1246     <literal>FactoryFilter</literal> is not a filter that filters
1247     factories, but a factory that produces filters; and
1248     <literal>FactoryStatic</literal> is a factory for the statically
1249     registered filters (as opposed to those that are dynamically
1250     loaded).
1251    </para>
1252   </section>
1253
1254   <section id="individual.classes">
1255    <title>Individual classes</title>
1256    <para>
1257     The classes making up the Metaproxy application are here listed by
1258     class-name, with the names of the source files that define them in
1259     parentheses.
1260    </para>
1261
1262    <section>
1263     <title><literal>mp::FactoryFilter</literal>
1264      (<filename>factory_filter.cpp</filename>)</title>
1265     <para>
1266      A factory class that exists primarily to provide the
1267      <literal>create()</literal> method, which takes the name of a
1268      filter class as its argument and returns a new filter of that
1269      type.  To enable this, the factory must first be populated by
1270      calling <literal>add_creator()</literal> for static filters (this
1271      is done by the <literal>FactoryStatic</literal> class, see below)
1272      and <literal>add_creator_dyn()</literal> for filters loaded
1273      dynamically.
1274     </para>
1275    </section>
1276
1277    <section>
1278     <title><literal>mp::FactoryStatic</literal>
1279      (<filename>factory_static.cpp</filename>)</title>
1280     <para>
1281      A subclass of <literal>FactoryFilter</literal> which is
1282      responsible for registering all the statically defined filter
1283      types.  It does this by knowing about all those filters'
1284      structures, which are listed in its constructor.  Merely
1285      instantiating this class registers all the static classes.  It is
1286      for the benefit of this class that <literal>struct
1287       metaproxy_1_filter_struct</literal> exists, and that all the filter
1288      classes provide a static object of that type.
1289     </para>
1290    </section>
1291
1292    <section>
1293     <title><literal>mp::filter::Base</literal>
1294      (<filename>filter.cpp</filename>)</title>
1295     <para>
1296      The virtual base class of all filters.  The filter API is, on the
1297      surface at least, extremely simple: two methods.
1298      <literal>configure()</literal> is passed a DOM tree representing
1299      that part of the configuration file that pertains to this filter
1300      instance, and is expected to walk that tree extracting relevant
1301      information.  And <literal>process()</literal> processes a
1302      package (see below).  That surface simplicitly is a bit
1303      misleading, as <literal>process()</literal> needs to know a lot
1304      about the <literal>Package</literal> class in order to do
1305      anything useful.
1306     </para>
1307    </section>
1308
1309    <section>
1310     <title><literal>mp::filter::AuthSimple</literal>,
1311      <literal>Backend_test</literal>, etc.
1312      (<filename>filter_auth_simple.cpp</filename>,
1313      <filename>filter_backend_test.cpp</filename>, etc.)</title>
1314     <para>
1315      Individual filters.  Each of these is implemented by a header and
1316      a source file, named <filename>filter_*.hpp</filename> and
1317      <filename>filter_*.cpp</filename> respectively.  All the header
1318      files should be pretty much identical, in that they declare the
1319      class, including a private <literal>Rep</literal> class and a
1320      member pointer to it, and the two public methods.  The only extra
1321      information in any filter header is additional private types and
1322      members (which should really all be in the <literal>Rep</literal>
1323      anyway) and private methods (which should also remain known only
1324      to the source file, but C++'s brain-damaged design requires this
1325      dirty laundry to be exhibited in public.  Thanks, Bjarne!)
1326     </para>
1327     <para>
1328      The source file for each filter needs to supply:
1329     </para>
1330     <itemizedlist>
1331      <listitem>
1332       <para>
1333        A definition of the private <literal>Rep</literal> class.
1334       </para>
1335      </listitem>
1336      <listitem>
1337       <para>
1338        Some boilerplate constructors and destructors.
1339       </para>
1340      </listitem>
1341      <listitem>
1342       <para>
1343        A <literal>configure()</literal> method that uses the
1344        appropriate XML fragment.
1345       </para>
1346      </listitem>
1347      <listitem>
1348       <para>
1349        Most important, the <literal>process()</literal> method that
1350        does all the actual work.
1351       </para>
1352      </listitem>
1353     </itemizedlist>
1354    </section>
1355
1356    <section>
1357     <title><literal>mp::Package</literal>
1358      (<filename>package.cpp</filename>)</title>
1359     <para>
1360      Represents a package on its way through the series of filters
1361      that make up a route.  This is essentially a Z39.50 or SRU APDU
1362      together with information about where it came from, which is
1363      modified as it passes through the various filters.
1364     </para>
1365    </section>
1366
1367    <section>
1368     <title><literal>mp::Pipe</literal>
1369      (<filename>pipe.cpp</filename>)</title>
1370     <para>
1371      This class provides a compatibility layer so that we have an IPC
1372      mechanism that works the same under Unix and Windows.  It's not
1373      particularly exciting.
1374     </para>
1375    </section>
1376
1377    <section>
1378     <title><literal>mp::RouterChain</literal>
1379      (<filename>router_chain.cpp</filename>)</title>
1380     <para>
1381      ### to be written
1382     </para>
1383    </section>
1384
1385    <section>
1386     <title><literal>mp::RouterFleXML</literal>
1387      (<filename>router_flexml.cpp</filename>)</title>
1388     <para>
1389      ### to be written
1390     </para>
1391    </section>
1392
1393    <section>
1394     <title><literal>mp::Session</literal>
1395      (<filename>session.cpp</filename>)</title>
1396     <para>
1397      ### to be written
1398     </para>
1399    </section>
1400
1401    <section>
1402     <title><literal>mp::ThreadPoolSocketObserver</literal>
1403      (<filename>thread_pool_observer.cpp</filename>)</title>
1404     <para>
1405      ### to be written
1406     </para>
1407    </section>
1408
1409    <section>
1410     <title><literal>mp::util</literal>
1411      (<filename>util.cpp</filename>)</title>
1412     <para>
1413      A namespace of various small utility functions and classes,
1414      collected together for convenience.  Most importantly, includes
1415      the <literal>mp::util::odr</literal> class, a wrapper for YAZ's
1416      ODR facilities.
1417     </para>
1418    </section>
1419
1420    <section>
1421     <title><literal>mp::xml</literal>
1422      (<filename>xmlutil.cpp</filename>)</title>
1423     <para>
1424      A namespace of various XML utility functions and classes,
1425      collected together for convenience.
1426     </para>
1427    </section>
1428   </section>
1429
1430
1431   <section id="other.source.files">
1432    <title>Other Source Files</title>
1433    <para>
1434     In addition to the Metaproxy source files that define the classes
1435     described above, there are a few additional files which are
1436     briefly described here:
1437    </para>
1438    <variablelist>
1439     <varlistentry>
1440      <term><literal>metaproxy_prog.cpp</literal></term>
1441      <listitem>
1442       <para>
1443        The main function of the <command>metaproxy</command> program.
1444       </para>
1445      </listitem>
1446     </varlistentry>
1447     <varlistentry>
1448      <term><literal>ex_router_flexml.cpp</literal></term>
1449      <listitem>
1450       <para>
1451        Identical to <literal>metaproxy_prog.cpp</literal>: it's not clear why.
1452       </para>
1453      </listitem>
1454     </varlistentry>
1455     <varlistentry>
1456      <term><literal>test_*.cpp</literal></term>
1457      <listitem>
1458       <para>
1459        Unit-tests for various modules.
1460       </para>
1461      </listitem>
1462     </varlistentry>
1463    </variablelist>
1464    <para>
1465     ### Still to be described:
1466     <literal>ex_filter_frontend_net.cpp</literal>,
1467     <literal>filter_dl.cpp</literal>,
1468     <literal>plainfile.cpp</literal>,
1469     <literal>tstdl.cpp</literal>.
1470    </para>
1471   </section>
1472  </chapter>
1473
1474
1475
1476  <chapter id="refguide">
1477   <title>Reference guide</title>
1478   <para>
1479    The material in this chapter is drawn directly from the individual
1480    manual entries.  In particular, the Metaproxy invocation section is
1481    available using <command>man metaproxy</command>, and the section
1482    on each individual filter is available using the name of the filter
1483    as the argument to the <command>man</command> command.
1484   </para>
1485
1486
1487   <section id="progref">
1488    <title>Metaproxy invocation</title>
1489    &progref;
1490   </section>
1491
1492
1493   <section id="filterref">
1494    <title>Reference guide to Metaproxy filters</title>
1495    &manref;
1496   </section>
1497  </chapter>
1498
1499
1500
1501  <!-- Keep this comment at the end of the file
1502  Local variables:
1503  mode: sgml
1504  sgml-omittag:t
1505  sgml-shorttag:t
1506  sgml-minimize-attributes:nil
1507  sgml-always-quote-attributes:t
1508  sgml-indent-step:1
1509  sgml-indent-data:t
1510  sgml-parent-document: "main.xml"
1511  sgml-local-catalogs: nil
1512  sgml-namecase-general:t
1513  End:
1514  -->