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