Beginnings of installation chapter.
[metaproxy-moved-to-github.git] / doc / book.xml
1 <!-- $Id: book.xml,v 1.15 2006-04-24 06:40:50 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    Cold bananas, fish, 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 folloing 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       </para>
146      </listitem>
147     </varlistentry>
148     <varlistentry><term><ulink url="&url.boost;">Boost</ulink></term>
149      <listitem>
150       <para>
151        The popular C++ library.
152       </para>
153      </listitem>
154     </varlistentry>
155    </variablelist>
156   </para>
157   <para>
158    In order to compile Metaproxy a modern C++ compiler is
159    required. Boost, in particular, requires the C++ compiler
160    to facilitate the newest features. Refer to Boost
161    <ulink url="&url.boost.compilers.status;">Compiler Status</ulink>
162    for more information.
163   </para>
164   <para>
165    We have succesfully used Metaproxy with Boost using the compilers
166    <ulink url="&url.gcc;">GCC</ulink> version 4.0 and
167    <ulink url="&url.vstudio;">Microsoft Visual Studio</ulink> 2003/2005.
168   </para>
169
170   <section id="installation.unix">
171    <title>Installation on Unix (from Source)</title>
172    <para>
173     Here is a quick step-by-step guide on how to compile all the
174     tools that Metaproxy uses. Only few systems have none of the required
175     tools binary packages. If, for example, Libxml2/libxslt are already
176     installed as development packages use those (and omit compilation).
177    </para>
178    
179    <para>
180     Libxml2/libxslt:
181    </para>
182    <screen>
183     gunzip -c libxml2-version.tar.gz|tar xf -
184     cd libxml2-version
185     ./configure
186     make
187     su
188     make install
189    </screen>
190    <screen>
191     gunzip -c libxslt-version.tar.gz|tar xf -
192     cd libxslt-version
193     ./configure
194     make
195     su
196     make install
197    </screen>
198    <para>
199     YAZ/YAZ++:
200    </para>
201    <screen>
202     gunzip -c yaz-version.tar.gz|tar xf -
203     cd yaz-version
204     ./configure
205     make
206     su
207     make install
208    </screen>
209    <screen>
210     gunzip -c yazpp-version.tar.gz|tar xf -
211     cd yazpp-version
212     ./configure
213     make
214     su
215     make install
216    </screen>
217    <para>
218     Boost:
219    </para>
220    <screen>
221     gunzip -c boost-version.tar.gz|tar xf -
222     cd boost-version
223     ./configure
224     make
225     su
226     make install
227    </screen>
228    <para>
229     Metaproxy:
230    </para>
231    <screen>
232     gunzip -c metaproxy-version.tar.gz|tar xf -
233     cd metaproxy-version
234     ./configure
235     make
236     su
237     make install
238    </screen>
239   </section>
240
241   <section id="installation.debian">
242    <title>Installation on Debian</title>
243    <para>
244     ### To be written
245    </para>
246    </section>
247
248   <section id="installation.windows">
249    <title>Installation on Windows</title>
250    <para>
251     ### To be written
252    </para>
253    </section>
254  </chapter>
255  
256  <chapter id="architecture">
257   <title>The Metaproxy Architecture</title>
258   <para>
259    The Metaproxy architecture is based on three concepts:
260    the <emphasis>package</emphasis>,
261    the <emphasis>route</emphasis>
262    and the <emphasis>filter</emphasis>.
263   </para>
264   <variablelist>
265    <varlistentry>
266     <term>Packages</term>
267     <listitem>
268      <para>
269       A package is request or response, encoded in some protocol,
270       issued by a client, making its way through Metaproxy, send to or
271       received from a server, or sent back to the client.
272      </para>
273      <para>
274       The core of a package is the protocol unit - for example, a
275       Z39.50 Init Request or Search Response, or an SRU searchRetrieve
276       URL or Explain Response.  In addition to this core, a package
277       also carries some extra information added and used by Metaproxy
278       itself.
279      </para>
280      <para>
281       In general, packages are doctored as they pass through
282       Metaproxy.  For example, when the proxy performs authentication
283       and authorisation on a Z39.50 Init request, it removes the
284       authentication credentials from the package so that they are not
285       passed onto the back-end server; and when search-response
286       packages are obtained from multiple servers, they are merged
287       into a single unified package that makes its way back to the
288       client.
289      </para>
290     </listitem>
291    </varlistentry>
292    <varlistentry>
293     <term>Routes</term>
294     <listitem>
295      <para>
296       Packages make their way through routes, which can be thought of
297       as programs that operate on the package data-type.  Each
298       incoming package initially makes its way through a default
299       route, but may be switched to a different route based on various
300       considerations.  Routes are made up of sequences of filters (see
301       below).
302      </para>
303     </listitem>
304    </varlistentry>
305    <varlistentry>
306     <term>Filters</term>
307     <listitem>
308      <para>
309       Filters provide the individual instructions within a route, and
310       effect the necessary transformations on packages.  A particular
311       configuration of Metaproxy is essentially a set of filters,
312       described by configuration details and arranged in order in one
313       or more routes.  There are many kinds of filter - about a dozen
314       at the time of writing with more appearing all the time - each
315       performing a specific function and configured by different
316       information.
317      </para>
318      <para>
319       The word ``filter'' is sometimes used rather loosely, in two
320       different ways: it may be used to mean a particular
321       <emphasis>type</emphasis> of filter, as when we speak of ``the
322       auth_simplefilter'' or ``the multi filter''; or it may be used
323       to be a specific <emphasis>instance</emphasis> of a filter
324       within a Metaproxy configuration.  For example, a single
325       configuration will often contain multiple instances of the
326       <literal>z3950_client</literal> filter.  In
327       operational terms, of these is a separate filter.  In practice,
328       context always make it clear which sense of the word ``filter''
329       is being used.
330      </para>
331      <para>
332       Extensibility of Metaproxy is primarily through the creation of
333       plugins that provide new filters.  The filter API is small and
334       conceptually simple, but there are many details to master.  See
335       the section below on
336       <link linkend="extensions">extensions</link>.
337      </para>
338     </listitem>
339    </varlistentry>
340   </variablelist>
341   <para>
342    Since packages are created and handled by the system itself, and
343    routes are conceptually simple, most of the remainder of this
344    document concentrates on filters.  After a brief overview of the
345    filter types follows, along with some thoughts on possible future
346    directions.
347   </para>
348  </chapter>
349
350
351
352  <chapter id="filters">
353   <title>Filters</title>
354   
355   
356   <section>
357    <title>Introductory notes</title>
358    <para>
359     It's useful to think of Metaproxy as an interpreter providing a small
360     number of primitives and operations, but operating on a very
361     complex data type, namely the ``package''.
362    </para>
363    <para>
364     A package represents a Z39.50 or SRU/W request (whether for Init,
365     Search, Scan, etc.)  together with information about where it came
366     from.  Packages are created by front-end filters such as
367     <literal>frontend_net</literal> (see below), which reads them from
368     the network; other front-end filters are possible.  They then pass
369     along a route consisting of a sequence of filters, each of which
370     transforms the package and may also have side-effects such as
371     generating logging.  Eventually, the route will yield a response,
372     which is sent back to the origin.
373    </para>
374    <para>
375     There are many kinds of filter: some that are defined statically
376     as part of Metaproxy, and others may be provided by third parties
377     and dynamically loaded.  They all conform to the same simple API
378     of essentially two methods: <function>configure()</function> is
379     called at startup time, and is passed a DOM tree representing that
380     part of the configuration file that pertains to this filter
381     instance: it is expected to walk that tree extracting relevant
382     information; and <function>process()</function> is called every
383     time the filter has to processes a package.
384    </para>
385    <para>
386     While all filters provide the same API, there are different modes
387     of functionality.  Some filters are sources: they create
388     packages
389     (<literal>frontend_net</literal>);
390     others are sinks: they consume packages and return a result
391     (<literal>z3950_client</literal>,
392     <literal>backend_test</literal>,
393     <literal>http_file</literal>);
394     the others are true filters, that read, process and pass on the
395     packages they are fed
396     (<literal>auth_simple</literal>,
397     <literal>log</literal>,
398     <literal>multi</literal>,
399     <literal>query_rewrite</literal>,
400     <literal>session_shared</literal>,
401     <literal>template</literal>,
402     <literal>virt_db</literal>).
403    </para>
404  </section>
405   
406   
407   <section id="overview.filter.types">
408    <title>Overview of filter types</title>
409    <para>
410     We now briefly consider each of the types of filter supported by
411     the core Metaproxy binary.  This overview is intended to give a
412     flavour of the available functionality; more detailed information
413     about each type of filter is included below in
414     <link linkend="filterref"
415           >the reference guide to Metaproxy filters</link>.
416    </para>
417    <para>
418     The filters are here named by the string that is used as the
419     <literal>type</literal> attribute of a
420     <literal>&lt;filter&gt;</literal> element in the configuration
421     file to request them, with the name of the class that implements
422     them in parentheses.  (The classname is not needed for normal
423     configuration and use of Metaproxy; it is useful only to
424     developers.)
425    </para>
426    <para>
427     The filters are here listed in alphabetical order:
428    </para>
429    
430    <section>
431     <title><literal>auth_simple</literal>
432      (mp::filter::AuthSimple)</title>
433     <para>
434      Simple authentication and authorisation.  The configuration
435      specifies the name of a file that is the user register, which
436      lists <varname>username</varname>:<varname>password</varname>
437      pairs, one per line, colon separated. When a session begins, it
438      is rejected unless username and passsword are supplied, and match
439      a pair in the register.  The configuration file may also specific
440      the name of another file that is the target register: this lists
441      lists <varname>username</varname>:<varname>dbname</varname>,<varname>dbname</varname>...
442      sets, one per line, with multiple database names separated by
443      commas.  When a search is processed, it is rejected unless the
444      database to be searched is one of those listed as available to
445      the user.
446     </para>
447    </section>
448    
449    <section>
450     <title><literal>backend_test</literal>
451     (mp::filter::Backend_test)</title>
452     <para>
453      A sink that provides dummy responses in the manner of the
454      <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
455      for testing.  Seriously, you don't need this.  Pretend you didn't
456      even read this section.
457     </para>
458    </section>
459    
460    <section>
461     <title><literal>frontend_net</literal>
462      (mp::filter::FrontendNet)</title>
463     <para>
464      A source that accepts Z39.50 connections from a port
465      specified in the configuration, reads protocol units, and
466      feeds them into the next filter in the route.  When the result is
467      revceived, it is returned to the original origin.
468     </para>
469    </section>
470
471    <section>
472     <title><literal>http_file</literal>
473      (mp::filter::HttpFile)</title>
474     <para>
475      A sink that returns the contents of files from the local
476      filesystem in response to HTTP requests.  (Yes, Virginia, this
477      does mean that Metaproxy is also a Web-server in its spare time.  So
478      far it does not contain either an email-reader or a Lisp
479      interpreter, but that day is surely coming.)
480     </para>
481    </section>
482    
483    <section>
484     <title><literal>log</literal>
485      (mp::filter::Log)</title>
486     <para>
487      Writes logging information to standard output, and passes on
488      the package unchanged.
489    </para>
490    </section>
491    
492    <section>
493    <title><literal>multi</literal>
494      (mp::filter::Multi)</title>
495     <para>
496      Performs multicast searching.
497      See
498      <link linkend="multidb">the extended discussion</link>
499      of virtual databases and multi-database searching below.
500     </para>
501    </section>
502    
503    <section>
504    <title><literal>query_rewrite</literal>
505      (mp::filter::QueryRewrite)</title>
506     <para>
507      Rewrites Z39.50 Type-1 and Type-101 (``RPN'') queries by a
508      three-step process: the query is transliterated from Z39.50
509      packet structures into an XML representation; that XML
510      representation is transformed by an XSLT stylesheet; and the
511      resulting XML is transliterated back into the Z39.50 packet
512      structure.
513     </para>
514    </section>
515    
516    <section>
517     <title><literal>session_shared</literal>
518      (mp::filter::SessionShared)</title>
519     <para>
520      When this is finished, it will implement global sharing of
521      result sets (i.e. between threads and therefore between
522      clients), yielding performance improvements especially when
523      incoming requests are from a stateless environment such as a
524      web-server, in which the client process representing a session
525      might be any one of many.  However:
526     </para>
527     <warning>
528      <para>
529       This filter is not yet completed.
530      </para>
531     </warning>
532    </section>
533    
534    <section>
535     <title><literal>template</literal>
536      (mp::filter::Template)</title>
537     <para>
538      Does nothing at all, merely passing the packet on.  (Maybe it
539      should be called <literal>nop</literal> or
540      <literal>passthrough</literal>?)  This exists not to be used, but
541      to be copied - to become the skeleton of new filters as they are
542      written.  As with <literal>backend_test</literal>, this is not
543      intended for civilians.
544     </para>
545    </section>
546    
547    <section>
548     <title><literal>virt_db</literal>
549      (mp::filter::Virt_db)</title>
550     <para>
551      Performs virtual database selection: based on the name of the
552      database in the search request, a server is selected, and its
553      address added to the request in a <literal>VAL_PROXY</literal>
554      otherInfo packet.  It will subsequently be used by a
555      <literal>z3950_client</literal> filter.
556      See
557      <link linkend="multidb">the extended discussion</link>
558      of virtual databases and multi-database searching below.
559     </para>
560    </section>
561    
562    <section>
563     <title><literal>z3950_client</literal>
564      (mp::filter::Z3950Client)</title>
565     <para>
566      Performs Z39.50 searching and retrieval by proxying the
567      packages that are passed to it.  Init requests are sent to the
568      address specified in the <literal>VAL_PROXY</literal> otherInfo
569      attached to the request: this may have been specified by client,
570      or generated by a <literal>virt_db</literal> filter earlier in
571      the route.  Subsequent requests are sent to the same address,
572      which is remembered at Init time in a Session object.
573     </para>
574   </section>
575   </section>
576   
577   
578   <section id="future.directions">
579    <title>Future directions</title>
580   <para>
581     Some other filters that do not yet exist, but which would be
582     useful, are briefly described.  These may be added in future
583     releases (or may be created by third parties, as loadable
584     modules).
585    </para>
586
587    <variablelist>
588     <varlistentry>
589      <term><literal>frontend_cli</literal> (source)</term>
590     <listitem>
591       <para>
592        Command-line interface for generating requests.
593       </para>
594      </listitem>
595     </varlistentry>
596     <varlistentry>
597      <term><literal>frontend_sru</literal> (source)</term>
598      <listitem>
599       <para>
600        Receive SRU (and perhaps SRW) requests.
601      </para>
602      </listitem>
603     </varlistentry>
604     <varlistentry>
605      <term><literal>sru2z3950</literal> (filter)</term>
606      <listitem>
607       <para>
608        Translate SRU requests into Z39.50 requests.
609      </para>
610      </listitem>
611     </varlistentry>
612     <varlistentry>
613      <term><literal>sru_client</literal> (sink)</term>
614      <listitem>
615       <para>
616        SRU searching and retrieval.
617       </para>
618      </listitem>
619     </varlistentry>
620     <varlistentry>
621      <term><literal>srw_client</literal> (sink)</term>
622      <listitem>
623       <para>
624        SRW searching and retrieval.
625       </para>
626      </listitem>
627     </varlistentry>
628     <varlistentry>
629      <term><literal>opensearch_client</literal> (sink)</term>
630      <listitem>
631       <para>
632        A9 OpenSearch searching and retrieval.
633       </para>
634      </listitem>
635     </varlistentry>
636    </variablelist>
637   </section>
638  </chapter>
639  
640  
641  
642  <chapter id="configuration">
643   <title>Configuration: the Metaproxy configuration file format</title>
644   
645   
646   <section>
647    <title>Introductory notes</title>
648    <para>
649     If Metaproxy is an interpreter providing operations on packages, then
650     its configuration file can be thought of as a program for that
651     interpreter.  Configuration is by means of a single file, the name
652     of which is supplied as the sole command-line argument to the
653     <command>metaproxy</command> program.  (See
654     <link linkend="progref">the reference guide</link>
655     below for more information on invoking Metaproxy.)
656    </para>
657    <para>
658     The configuration files are written in XML.  (But that's just an
659     implementation detail - they could just as well have been written
660     in YAML or Lisp-like S-expressions, or in a custom syntax.)
661    </para>
662    <para>
663     Since XML has been chosen, an XML schema,
664     <filename>config.xsd</filename>, is provided for validating
665     configuration files.  This file is supplied in the
666     <filename>etc</filename> directory of the Metaproxy distribution.  It
667     can be used by (among other tools) the <command>xmllint</command>
668     program supplied as part of the <literal>libxml2</literal>
669     distribution:
670    </para>
671    <screen>
672     xmllint --noout --schema etc/config.xsd my-config-file.xml
673    </screen>
674    <para>
675     (A recent version of <literal>libxml2</literal> is required, as
676     support for XML Schemas is a relatively recent addition.)
677    </para>
678   </section>
679   
680   <section id="overview.xml.structure">
681    <title>Overview of XML structure</title>
682    <para>
683     All elements and attributes are in the namespace
684     <ulink url="http://indexdata.dk/yp2/config/1"/>.
685      This is most easily achieved by setting the default namespace on
686      the top-level element, as here:
687    </para>
688    <screen>
689     &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
690    </screen>
691    <para>
692     The top-level element is &lt;yp2&gt;.  This contains a
693     &lt;start&gt; element, a &lt;filters&gt; element and a
694     &lt;routes&gt; element, in that order.  &lt;filters&gt; is
695     optional; the other two are mandatory.  All three are
696     non-repeatable.
697    </para>
698   <para>
699     The &lt;start&gt; element is empty, but carries a
700     <literal>route</literal> attribute, whose value is the name of
701     route at which to start running - analogous to the name of the
702     start production in a formal grammar.
703    </para>
704   <para>
705     If present, &lt;filters&gt; contains zero or more &lt;filter&gt;
706     elements.  Each filter carries a <literal>type</literal> attribute
707     which specifies what kind of filter is being defined
708     (<literal>frontend_net</literal>, <literal>log</literal>, etc.)
709     and contain various elements that provide suitable configuration
710     for a filter of its type.  The filter-specific elements are
711     described in
712     <link linkend="filterref">the reference guide below</link>.
713     Filters defined in this part of the file must carry an
714     <literal>id</literal> attribute so that they can be referenced
715     from elsewhere.
716    </para>
717    <para>
718     &lt;routes&gt; contains one or more &lt;route&gt; elements, each
719     of which must carry an <literal>id</literal> element.  One of the
720     routes must have the ID value that was specified as the start
721     route in the &lt;start&gt; element's <literal>route</literal>
722     attribute.  Each route contains zero or more &lt;filter&gt;
723     elements.  These are of two types.  They may be empty, but carry a
724     <literal>refid</literal> attribute whose value is the same as the
725     <literal>id</literal> of a filter previously defined in the
726     &lt;filters&gt; section.  Alternatively, a route within a filter
727     may omit the <literal>refid</literal> attribute, but contain
728     configuration elements similar to those used for filters defined
729     in the &lt;filters&gt; section.  (In other words, each filter in a
730     route may be included either by reference or by physical
731     inclusion.)
732    </para>
733   </section>
734
735
736   <section id="example.configuration">
737    <title>An example configuration</title>
738    <para>
739     The following is a small, but complete, Metaproxy configuration
740     file (included in the distribution as
741     <literal>metaproxy/etc/config0.xml</literal>).
742     This file defines a very simple configuration that simply proxies
743     to whatever backend server the client requests, but logs each
744     request and response.  This can be useful for debugging complex
745     client-server dialogues.
746    </para>
747    <screen><![CDATA[
748 <?xml version="1.0"?>
749 <yp2 xmlns="http://indexdata.dk/yp2/config/1">
750   <start route="start"/>
751   <filters>
752     <filter id="frontend" type="frontend_net">
753       <port>@:9000</port>
754     </filter>
755     <filter id="backend" type="z3950_client">
756     </filter>
757   </filters>
758   <routes>  
759     <route id="start">
760       <filter refid="frontend"/>
761       <filter type="log"/>
762       <filter refid="backend"/>
763     </route>
764   </routes>
765 </yp2>
766 ]]></screen>
767    <para>
768     It works by defining a single route, called
769     <literal>start</literal>, which consists of a sequence of three
770     filters.  The first and last of these are included by reference:
771     their <literal>&lt;filter&gt;</literal> elements have
772     <literal>refid</literal> attributes that refer to filters defined
773     within the prior <literal>&lt;filters&gt;</literal> section.  The
774     middle filter is included inline in the route.
775    </para>
776    <para>
777     The three filters in the route are as follows: first, a
778     <literal>frontend_net</literal> filter accepts Z39.50 requests
779     from any host on port 9000; then these requests are passed through
780     a <literal>log</literal> filter that emits a message for each
781     request; they are then fed into a <literal>z3950_client</literal>
782     filter, which forwards the requests to the client-specified
783     backend Z39.509 server.  When the response arrives, it is handed
784     back to the <literal>log</literal> filter, which emits another
785     message; and then to the front-end filter, which returns the
786     response to the client.
787    </para>
788   </section>
789  </chapter>
790
791
792
793  <chapter id="multidb">
794   <title>Virtual databases and multi-database searching</title>
795
796
797   <section>
798    <title>Introductory notes</title>
799    <warning>
800     <title>Lark's vomit</title>
801     <para>
802      This chapter goes into a level of technical detail that is
803      probably not necessary in order to configure and use Metaproxy.
804      It is provided only for those who like to know how things work.
805      You should feel free to skip on to the next section if this one
806      doesn't seem like fun.
807     </para>
808    </warning>
809    <para>
810     Two of Metaproxy's filters are concerned with multiple-database
811     operations.  Of these, <literal>virt_db</literal> can work alone
812     to control the routing of searches to one of a number of servers,
813     while <literal>multi</literal> can work with the output of
814     <literal>virt_db</literal> to perform multicast searching, merging
815     the results into a unified result-set.  The interaction between
816     these two filters is necessarily complex: it reflecting the real,
817     irreducible complexity of multicast searching in a protocol such
818     as Z39.50 that separates initialisation from searching, and in
819     which the database to be searched is not known at initialisation
820     time.
821    </para>
822    <para>
823     Hold on tight - this may get a little hairy.
824    </para>
825    <para>
826     In the general course of things, a Z39.50 Init request may carry
827     with it an otherInfo packet of type <literal>VAL_PROXY</literal>,
828     whose value indicates the address of a Z39.50 server to which the
829     ultimate connection is to be made.  (This otherInfo packet is
830     supported by YAZ-based Z39.50 clients and servers, but has not yet
831     been ratified by the Maintenance Agency and so is not widely used
832     in non-Index Data software.  We're working on it.)
833     The <literal>VAL_PROXY</literal> packet functions
834     analogously to the absoluteURI-style Request-URI used with the GET
835     method when a web browser asks a proxy to forward its request: see
836     the
837     <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2"
838            >Request-URI</ulink>
839     section of
840     <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616.html"
841            >the HTTP 1.1 specification</ulink>.
842    </para>
843    <para>
844     The role of the <literal>virt_db</literal> filter is to rewrite
845     this otherInfo packet dependent on the virtual database that the
846     client wants to search.  For example, a <literal>virt_db</literal>
847     filter could be set up so that searches in the virtual database
848     ``lc'' are forwarded to the Library of Congress server, and
849     searches in the virtual database ``id'' are forwarded to the toy
850     GILS database that Index Data hosts for testing purposes.  A
851     <literal>virt_db</literal> configuration to make this switch would
852     look like this:
853    </para>
854    <screen><![CDATA[
855     <filter type="virt_db">
856       <virtual>
857         <database>lc</database>
858         <target>z3950.loc.gov:7090/Voyager</target>
859       </virtual>
860       <virtual>
861         <database>id</database>
862         <target>indexdata.dk/gils</target>
863       </virtual>
864     </filter>]]></screen>
865    <para>
866     When Metaproxy receives a Z39.50 Init request from a client, it
867     doesn't immediately forward that request to the back-end server.
868     Why not?  Because it doesn't know <emphasis>which</emphasis>
869     back-end server to forward it to until the client sends a search
870     request that specifies the database that it wants to search in.
871     Instead, it just treasures the Init request up in its heart; and,
872     later, the first time the client does a search on one of the
873     specified virtual databases, a connection is forged to the
874     appropriate server and the Init request is forwarded to it.  If,
875     later in the session, the same client searches in a different
876     virtual database, then a connection is forged to the server that
877     hosts it, and the same cached Init request is forwarded there,
878     too.
879    </para>
880    <para>
881     All of this clever Init-delaying is done by the
882     <literal>frontend_net</literal> filter.  The
883     <literal>virt_db</literal> filter knows nothing about it; in
884     fact, because the Init request that is received from the client
885     doesn't get forwarded until a Search reqeust is received, the
886     <literal>virt_db</literal> filter (and the
887     <literal>z3950_client</literal> filter behind it) doesn't even get
888     invoked at Init time.  The <emphasis>only</emphasis> thing that a
889     <literal>virt_db</literal> filter ever does is rewrite the
890     <literal>VAL_PROXY</literal> otherInfo in the requests that pass
891     through it.
892    </para>
893   </section>
894  </chapter>
895
896
897
898  <chapter id="extensions">
899   <title>Writing extensions for Metaproxy</title>
900   <para>### To be written</para>
901  </chapter>
902
903
904
905
906  <chapter id="classes">
907   <title>Classes in the Metaproxy source code</title>
908
909
910   <section>
911    <title>Introductory notes</title>
912    <para>
913     <emphasis>Stop!  Do not read this!</emphasis>
914     You won't enjoy it at all.  You should just skip ahead to
915     <link linkend="refguide">the reference guide</link>,
916     which tells
917     <!-- The remainder of this paragraph is lifted verbatim from
918     Douglas Adams' _Hitch Hiker's Guide to the Galaxy_, chapter 8 -->
919     you things you really need to know, like the fact that the
920     fabulously beautiful planet Bethselamin is now so worried about
921     the cumulative erosion by ten billion visiting tourists a year
922     that any net imbalance between the amount you eat and the amount
923     you excrete whilst on the planet is surgically removed from your
924     bodyweight when you leave: so every time you go to the lavatory it
925     is vitally important to get a receipt.
926    </para>
927    <para>
928     This chapter contains documentation of the Metaproxy source code, and is
929     of interest only to maintainers and developers.  If you need to
930     change Metaproxy's behaviour or write a new filter, then you will most
931     likely find this chapter helpful.  Otherwise it's a waste of your
932     good time.  Seriously: go and watch a film or something.
933     <citetitle>This is Spinal Tap</citetitle> is particularly good.
934    </para>
935    <para>
936     Still here?  OK, let's continue.
937    </para>
938    <para>
939     In general, classes seem to be named big-endianly, so that
940     <literal>FactoryFilter</literal> is not a filter that filters
941     factories, but a factory that produces filters; and
942     <literal>FactoryStatic</literal> is a factory for the statically
943     registered filters (as opposed to those that are dynamically
944     loaded).
945    </para>
946   </section>
947
948   <section id="individual.classes">
949    <title>Individual classes</title>
950    <para>
951     The classes making up the Metaproxy application are here listed by
952     class-name, with the names of the source files that define them in
953     parentheses.
954    </para>
955
956    <section>
957     <title><literal>mp::FactoryFilter</literal>
958      (<filename>factory_filter.cpp</filename>)</title>
959     <para>
960      A factory class that exists primarily to provide the
961      <literal>create()</literal> method, which takes the name of a
962      filter class as its argument and returns a new filter of that
963      type.  To enable this, the factory must first be populated by
964      calling <literal>add_creator()</literal> for static filters (this
965      is done by the <literal>FactoryStatic</literal> class, see below)
966      and <literal>add_creator_dyn()</literal> for filters loaded
967      dynamically.
968     </para>
969    </section>
970
971    <section>
972     <title><literal>mp::FactoryStatic</literal>
973      (<filename>factory_static.cpp</filename>)</title>
974     <para>
975      A subclass of <literal>FactoryFilter</literal> which is
976      responsible for registering all the statically defined filter
977      types.  It does this by knowing about all those filters'
978      structures, which are listed in its constructor.  Merely
979      instantiating this class registers all the static classes.  It is
980      for the benefit of this class that <literal>struct
981       metaproxy_1_filter_struct</literal> exists, and that all the filter
982      classes provide a static object of that type.
983     </para>
984    </section>
985
986    <section>
987     <title><literal>mp::filter::Base</literal>
988      (<filename>filter.cpp</filename>)</title>
989     <para>
990      The virtual base class of all filters.  The filter API is, on the
991      surface at least, extremely simple: two methods.
992      <literal>configure()</literal> is passed a DOM tree representing
993      that part of the configuration file that pertains to this filter
994      instance, and is expected to walk that tree extracting relevant
995      information.  And <literal>process()</literal> processes a
996      package (see below).  That surface simplicitly is a bit
997      misleading, as <literal>process()</literal> needs to know a lot
998      about the <literal>Package</literal> class in order to do
999      anything useful.
1000     </para>
1001    </section>
1002
1003    <section>
1004     <title><literal>mp::filter::AuthSimple</literal>,
1005      <literal>Backend_test</literal>, etc.
1006      (<filename>filter_auth_simple.cpp</filename>,
1007      <filename>filter_backend_test.cpp</filename>, etc.)</title>
1008     <para>
1009      Individual filters.  Each of these is implemented by a header and
1010      a source file, named <filename>filter_*.hpp</filename> and
1011      <filename>filter_*.cpp</filename> respectively.  All the header
1012      files should be pretty much identical, in that they declare the
1013      class, including a private <literal>Rep</literal> class and a
1014      member pointer to it, and the two public methods.  The only extra
1015      information in any filter header is additional private types and
1016      members (which should really all be in the <literal>Rep</literal>
1017      anyway) and private methods (which should also remain known only
1018      to the source file, but C++'s brain-damaged design requires this
1019      dirty laundry to be exhibited in public.  Thanks, Bjarne!)
1020     </para>
1021     <para>
1022      The source file for each filter needs to supply:
1023     </para>
1024     <itemizedlist>
1025      <listitem>
1026       <para>
1027        A definition of the private <literal>Rep</literal> class.
1028       </para>
1029      </listitem>
1030      <listitem>
1031       <para>
1032        Some boilerplate constructors and destructors.
1033       </para>
1034      </listitem>
1035      <listitem>
1036       <para>
1037        A <literal>configure()</literal> method that uses the
1038        appropriate XML fragment.
1039       </para>
1040      </listitem>
1041      <listitem>
1042       <para>
1043        Most important, the <literal>process()</literal> method that
1044        does all the actual work.
1045       </para>
1046      </listitem>
1047     </itemizedlist>
1048    </section>
1049
1050    <section>
1051     <title><literal>mp::Package</literal>
1052      (<filename>package.cpp</filename>)</title>
1053     <para>
1054      Represents a package on its way through the series of filters
1055      that make up a route.  This is essentially a Z39.50 or SRU APDU
1056      together with information about where it came from, which is
1057      modified as it passes through the various filters.
1058     </para>
1059    </section>
1060
1061    <section>
1062     <title><literal>mp::Pipe</literal>
1063      (<filename>pipe.cpp</filename>)</title>
1064     <para>
1065      This class provides a compatibility layer so that we have an IPC
1066      mechanism that works the same under Unix and Windows.  It's not
1067      particularly exciting.
1068     </para>
1069    </section>
1070
1071    <section>
1072     <title><literal>mp::RouterChain</literal>
1073      (<filename>router_chain.cpp</filename>)</title>
1074     <para>
1075      ### to be written
1076     </para>
1077    </section>
1078
1079    <section>
1080     <title><literal>mp::RouterFleXML</literal>
1081      (<filename>router_flexml.cpp</filename>)</title>
1082     <para>
1083      ### to be written
1084     </para>
1085    </section>
1086
1087    <section>
1088     <title><literal>mp::Session</literal>
1089      (<filename>session.cpp</filename>)</title>
1090     <para>
1091      ### to be written
1092     </para>
1093    </section>
1094
1095    <section>
1096     <title><literal>mp::ThreadPoolSocketObserver</literal>
1097      (<filename>thread_pool_observer.cpp</filename>)</title>
1098     <para>
1099      ### to be written
1100     </para>
1101    </section>
1102
1103    <section>
1104     <title><literal>mp::util</literal>
1105      (<filename>util.cpp</filename>)</title>
1106     <para>
1107      A namespace of various small utility functions and classes,
1108      collected together for convenience.  Most importantly, includes
1109      the <literal>mp::util::odr</literal> class, a wrapper for YAZ's
1110      ODR facilities.
1111     </para>
1112    </section>
1113
1114    <section>
1115     <title><literal>mp::xml</literal>
1116      (<filename>xmlutil.cpp</filename>)</title>
1117     <para>
1118      A namespace of various XML utility functions and classes,
1119      collected together for convenience.
1120     </para>
1121    </section>
1122   </section>
1123
1124
1125   <section id="other.source.files">
1126    <title>Other Source Files</title>
1127    <para>
1128     In addition to the Metaproxy source files that define the classes
1129     described above, there are a few additional files which are
1130     briefly described here:
1131    </para>
1132    <variablelist>
1133     <varlistentry>
1134      <term><literal>metaproxy_prog.cpp</literal></term>
1135      <listitem>
1136       <para>
1137        The main function of the <command>metaproxy</command> program.
1138       </para>
1139      </listitem>
1140     </varlistentry>
1141     <varlistentry>
1142      <term><literal>ex_router_flexml.cpp</literal></term>
1143      <listitem>
1144       <para>
1145        Identical to <literal>metaproxy_prog.cpp</literal>: it's not clear why.
1146       </para>
1147      </listitem>
1148     </varlistentry>
1149     <varlistentry>
1150      <term><literal>test_*.cpp</literal></term>
1151      <listitem>
1152       <para>
1153        Unit-tests for various modules.
1154       </para>
1155      </listitem>
1156     </varlistentry>
1157    </variablelist>
1158    <para>
1159     ### Still to be described:
1160     <literal>ex_filter_frontend_net.cpp</literal>,
1161     <literal>filter_dl.cpp</literal>,
1162     <literal>plainfile.cpp</literal>,
1163     <literal>tstdl.cpp</literal>.
1164    </para>
1165   </section>
1166  </chapter>
1167
1168
1169
1170  <chapter id="refguide">
1171   <title>Reference guide</title>
1172   <para>
1173    The material in this chapter is drawn directly from the individual
1174    manual entries.  In particular, the Metaproxy invocation section is
1175    available using <command>man metaproxy</command>, and the section
1176    on each individual filter is available using the name of the filter
1177    as the argument to the <command>man</command> command.
1178   </para>
1179
1180
1181   <section id="progref">
1182    <title>Metaproxy invocation</title>
1183    &progref;
1184   </section>
1185
1186
1187   <section id="filterref">
1188    <title>Reference guide to Metaproxy filters</title>
1189    &manref;
1190   </section>
1191  </chapter>
1192
1193
1194
1195  <!-- Keep this comment at the end of the file
1196  Local variables:
1197  mode: sgml
1198  sgml-omittag:t
1199  sgml-shorttag:t
1200  sgml-minimize-attributes:nil
1201  sgml-always-quote-attributes:t
1202  sgml-indent-step:1
1203  sgml-indent-data:t
1204  sgml-parent-document: "main.xml"
1205  sgml-local-catalogs: nil
1206  sgml-namecase-general:t
1207  nxml-child-indent: 1
1208  End:
1209  -->