Much new material, lots of cleaning up, etc.
[metaproxy-moved-to-github.git] / doc / book.xml
1 <!-- $Id: book.xml,v 1.6 2006-04-19 15:43:40 mike Exp $ -->
2  <bookinfo>
3   <title>Metaproxy - User's Guide and Reference</title>
4   <author>
5    <firstname>Mike</firstname><surname>Taylor</surname>
6   </author>
7   <author>
8    <firstname>Adam</firstname><surname>Dickmeiss</surname>
9   </author>
10   <copyright>
11    <year>2006</year>
12    <holder>Index Data</holder>
13   </copyright>
14   <abstract>
15    <simpara>
16     Metaproxy is a universal Z39.50/SRU router, proxy and encapsulated
17     metasearcher.  It accepts, processes, interprets and redirects
18     requests from IR clients using standard protocols such as
19     ANSI/NISO Z39.50, SRU and SRW, as well as functioning as a limited
20     HTTP server.  Metaproxy is configured by an XML file which
21     specifies how the software should function in terms of routes that
22     the request packets can take through the proxy, each step on a
23     route being an instantiation of a filter.  Filters come in many
24     types, one for each operation: accepting Z39.50 packets, logging,
25     query transformation, multiplexing, etc.  Further filter-types can
26     be added as loadable modules to extend Metaproxy functionality,
27     using the filter API.
28    </simpara>
29    <simpara>
30     The terms under which Metaproxy will be distributed have yet to be
31     established, but it will not necessarily be open source; so users
32     should not at this stage redistribute the code without explicit
33     written permission from the copyright holders, Index Data ApS.
34    </simpara>
35   </abstract>
36  </bookinfo>
37
38  <chapter id="introduction">
39   <title>Introduction</title>
40   
41   
42    <para>
43     <ulink url="http://indexdata.dk/metaproxy/">Metaproxy</ulink>
44     is a standalone program that acts as a universal router, proxy and
45     encapsulated metasearcher for information retrieval protocols such
46     as Z39.50 and SRU/SRW.  To clients, it acts as a server of these
47     protocols: it can be searched, records can be retrieved from it,
48     etc.  To servers, it acts as a client: it searches in them,
49     retrieves records from them, etc.  it satisfies its clients'
50     requests by transforming them, multiplexing them, forwarding them
51     on to zero or more servers, merging the results, transforming
52     them, and delivering them back to the client.  In addition, it
53     acts as a simple HTTP server; support for further protocols can be
54     added in a module fashion, through the creation of new filters.
55    </para>
56    <screen>
57     Anything goes in!
58     Anything goes out!
59     Cold bananas, fish, pyjamas,
60     Mutton, beef and trout!
61         - attributed to Cole Porter.
62    </screen>
63    <para>
64     Metaproxy is a more capable alternative to
65     <ulink url="http://indexdata.dk/yazproxy/">YAZ Proxy</ulink>,
66     being more powerful, flexible, configurable and extensible.  Among
67     its many advantages over the older, more pedestrian work are
68     support for multiplexing (encapsulated metasearching), routing by
69     database name, authentication and authorisation and serving local
70     files via HTTP.  Equally significant, its modular architecture
71     facilitites the creation of pluggable modules implementing further
72     functionality.
73    </para>
74  </chapter>
75
76
77
78  <chapter id="licence">
79   <title>The Metaproxy Licence</title>
80   <para>
81    <emphasis role="strong">
82      No decision has yet been made on the terms under which
83      Metaproxy will be distributed.
84    </emphasis>
85    It is possible that, unlike
86    other Index Data products, metaproxy may not be released under a
87    free-software licence such as the GNU GPL.  Until a decision is
88    made and a public statement made, then, and unless it has been
89    delivered to you other specific terms, please treat Metaproxy as
90    though it were proprietary software.
91    The code should not be redistributed without explicit
92    written permission from the copyright holders, Index Data ApS.
93   </para>
94  </chapter>
95
96
97
98  <chapter id="architecture">
99   <title>The Metaproxy Architecture</title>
100   <para>
101    The Metaproxy architecture is based on three concepts:
102    the <emphasis>package</emphasis>,
103    the <emphasis>route</emphasis>
104    and the <emphasis>filter</emphasis>.
105   </para>
106   <variablelist>
107    <varlistentry>
108     <term>Packages</term>
109     <listitem>
110      <para>
111       A package is request or response, encoded in some protocol,
112       issued by a client, making its way through Metaproxy, send to or
113       received from a server, or sent back to the client.
114      </para>
115      <para>
116       The core of a package is the protocol unit - for example, a
117       Z39.50 Init Request or Search Response, or an SRU searchRetrieve
118       URL or Explain Response.  In addition to this core, a package
119       also carries some extra information added and used by Metaproxy
120       itself.
121      </para>
122      <para>
123       In general, packages are doctored as they pass through
124       Metaproxy.  For example, when the proxy performs authentication
125       and authorisation on a Z39.50 Init request, it removes the
126       authentication credentials from the package so that they are not
127       passed onto the back-end server; and when search-response
128       packages are obtained from multiple servers, they are merged
129       into a single unified package that makes its way back to the
130       client.
131      </para>
132     </listitem>
133    </varlistentry>
134    <varlistentry>
135     <term>Routes</term>
136     <listitem>
137      <para>
138       Packages make their way through routes, which can be thought of
139       as programs that operate on the package data-type.  Each
140       incoming package initially makes its way through a default
141       route, but may be switched to a different route based on various
142       considerations.  Routes are made up of sequences of filters (see
143       below).
144      </para>
145     </listitem>
146    </varlistentry>
147    <varlistentry>
148     <term>Filters</term>
149     <listitem>
150      <para>
151       Filters provide the individual instructions within a route, and
152       effect the necessary transformations on packages.  A particular
153       configuration of Metaproxy is essentially a set of filters,
154       described by configuration details and arranged in order in one
155       or more routes.  There are many kinds of filter - about a dozen
156       at the time of writing with more appearing all the time - each
157       performing a specific function and configured by different
158       information.
159      </para>
160      <para>
161       The word ``filter'' is sometimes used rather loosely, in two
162       different ways: it may be used to mean a particular
163       <emphasis>type</emphasis> of filter, as when we speak of ``the
164       auth_simplefilter'' or ``the multi filter''; or it may be used
165       to be a specific <emphasis>instance</emphasis> of a filter
166       within a Metaproxy configuration.  For example, a single
167       configuration will often contain multiple instances of the
168       <literal>z3950_client</literal> filter.  In
169       operational terms, of these is a separate filter.  In practice,
170       context always make it clear which sense of the word ``filter''
171       is being used.
172      </para>
173      <para>
174       Extensibility of Metaproxy is primarily through the creation of
175       plugins that provide new filters.  The filter API is small and
176       conceptually simple, but there are many details to master.  See
177       the section below on
178       <link linkend="extensions">extensions</link>.
179      </para>
180     </listitem>
181    </varlistentry>
182   </variablelist>
183   <para>
184    Since packages are created and handled by the system itself, and
185    routes are conceptually simple, most of the remainder of this
186    document concentrates on filters.  After a brief overview of the
187    filter types follows, along with some thoughts on possible future
188    directions.
189   </para>
190  </chapter>
191
192
193
194  <chapter id="filters">
195   <title>Filters</title>
196   
197   
198   <section>
199    <title>Introductory notes</title>
200    <para>
201     It's useful to think of Metaproxy as an interpreter providing a small
202     number of primitives and operations, but operating on a very
203     complex data type, namely the ``package''.
204    </para>
205    <para>
206     A package represents a Z39.50 or SRW/U request (whether for Init,
207     Search, Scan, etc.)  together with information about where it came
208     from.  Packages are created by front-end filters such as
209     <literal>frontend_net</literal> (see below), which reads them from
210     the network; other front-end filters are possible.  They then pass
211     along a route consisting of a sequence of filters, each of which
212     transforms the package and may also have side-effects such as
213     generating logging.  Eventually, the route will yield a response,
214     which is sent back to the origin.
215    </para>
216    <para>
217     There are many kinds of filter: some that are defined statically
218     as part of Metaproxy, and others may be provided by third parties
219     and dynamically loaded.  They all conform to the same simple API
220     of essentially two methods: <function>configure()</function> is
221     called at startup time, and is passed a DOM tree representing that
222     part of the configuration file that pertains to this filter
223     instance: it is expected to walk that tree extracting relevant
224     information; and <function>process()</function> is called every
225     time the filter has to processes a package.
226    </para>
227    <para>
228     While all filters provide the same API, there are different modes
229     of functionality.  Some filters are sources: they create
230     packages
231     (<literal>frontend_net</literal>);
232     others are sinks: they consume packages and return a result
233     (<literal>z3950_client</literal>,
234     <literal>backend_test</literal>,
235     <literal>http_file</literal>);
236     the others are true filters, that read, process and pass on the
237     packages they are fed
238     (<literal>auth_simple</literal>,
239     <literal>log</literal>,
240     <literal>multi</literal>,
241     <literal>query_rewrite</literal>,
242     <literal>session_shared</literal>,
243     <literal>template</literal>,
244     <literal>virt_db</literal>).
245    </para>
246  </section>
247   
248   
249   <section>
250    <title>Overview of filter types</title>
251    <para>
252     We now briefly consider each of the types of filter supported by
253     the core Metaproxy binary.  This overview is intended to give a
254     flavour of the available functionality; more detailed information
255     about each type of filter is included below in the Module
256     Reference.
257    </para>
258    <para>
259     The filters are here named by the string that is used as the
260     <literal>type</literal> attribute of a
261     <literal>&lt;filter&gt;</literal> element in the configuration
262     file to request them, with the name of the class that implements
263     them in parentheses.  (The classname is not needed for normal
264     configuration and use of Metaproxy; it is useful only to
265     developers.)
266    </para>
267    <para>
268     The filters are here listed in alphabetical order:
269    </para>
270    
271    <section>
272     <title><literal>auth_simple</literal>
273      (mp::filter::AuthSimple)</title>
274     <para>
275      Simple authentication and authorisation.  The configuration
276      specifies the name of a file that is the user register, which
277      lists <varname>username</varname>:<varname>password</varname>
278      pairs, one per line, colon separated. When a session begins, it
279      is rejected unless username and passsword are supplied, and match
280      a pair in the register.  The configuration file may also specific
281      the name of another file that is the target register: this lists
282      lists <varname>username</varname>:<varname>dbname</varname>,<varname>dbname</varname>...
283      sets, one per line, with multiple database names separated by
284      commas.  When a search is processed, it is rejected unless the
285      database to be searched is one of those listed as available to
286      the user.
287     </para>
288    </section>
289    
290    <section>
291     <title><literal>backend_test</literal>
292     (mp::filter::Backend_test)</title>
293     <para>
294      A sink that provides dummy responses in the manner of the
295      <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
296      for testing.  Seriously, you don't need this.  Pretend you didn't
297      even read this section.
298     </para>
299    </section>
300    
301    <section>
302     <title><literal>frontend_net</literal>
303      (mp::filter::FrontendNet)</title>
304     <para>
305      A source that accepts Z39.50 and SRW connections from a port
306      specified in the configuration, reads protocol units, and
307      feeds them into the next filter in the route.  When the result is
308      revceived, it is returned to the original origin.
309     </para>
310    </section>
311
312    <section>
313     <title><literal>http_file</literal>
314      (mp::filter::HttpFile)</title>
315     <para>
316      A sink that returns the contents of files from the local
317      filesystem in response to HTTP requests.  (Yes, Virginia, this
318      does mean that Metaproxy is also a Web-server in its spare time.  So
319      far it does not contain either an email-reader or a Lisp
320      interpreter, but that day is surely coming.)
321     </para>
322    </section>
323    
324    <section>
325     <title><literal>log</literal>
326      (mp::filter::Log)</title>
327     <para>
328      Writes logging information to standard output, and passes on
329      the package unchanged.
330    </para>
331    </section>
332    
333    <section>
334    <title><literal>multi</literal>
335      (mp::filter::Multi)</title>
336     <para>
337      Performs multicast searching.
338      See
339      <link linkend="multidb">the extended discussion</link>
340      of virtual databases and multi-database searching below.
341     </para>
342    </section>
343    
344    <section>
345    <title><literal>query_rewrite</literal>
346      (mp::filter::QueryRewrite)</title>
347     <para>
348      Rewrites Z39.50 Type-1 and Type-101 (``RPN'') queries by a
349      three-step process: the query is transliterated from Z39.50
350      packet structures into an XML representation; that XML
351      representation is transformed by an XSLT stylesheet; and the
352      resulting XML is transliterated back into the Z39.50 packet
353      structure.
354     </para>
355    </section>
356    
357    <section>
358     <title><literal>session_shared</literal>
359      (mp::filter::SessionShared)</title>
360     <para>
361      When this is finished, it will implement global sharing of
362      result sets (i.e. between threads and therefore between
363      clients), yielding performance improvements especially when
364      incoming requests are from a stateless environment such as a
365      web-server, in which the client process representing a session
366      might be any one of many.  However:
367     </para>
368     <warning>
369      <para>
370       This filter is not yet completed.
371      </para>
372     </warning>
373    </section>
374    
375    <section>
376     <title><literal>template</literal>
377      (mp::filter::Template)</title>
378     <para>
379      Does nothing at all, merely passing the packet on.  (Maybe it
380      should be called <literal>nop</literal> or
381      <literal>passthrough</literal>?)  This exists not to be used, but
382      to be copied - to become the skeleton of new filters as they are
383      written.  As with <literal>backend_test</literal>, this is not
384      intended for civilians.
385     </para>
386    </section>
387    
388    <section>
389     <title><literal>virt_db</literal>
390      (mp::filter::Virt_db)</title>
391     <para>
392      Performs virtual database selection: based on the name of the
393      database in the search request, a server is selected, and its
394      address added to the request in a <literal>VAL_PROXY</literal>
395      otherInfo packet.  It will subsequently be used by a
396      <literal>z3950_client</literal> filter.
397      See
398      <link linkend="multidb">the extended discussion</link>
399      of virtual databases and multi-database searching below.
400     </para>
401    </section>
402    
403    <section>
404     <title><literal>z3950_client</literal>
405      (mp::filter::Z3950Client)</title>
406     <para>
407      Performs Z39.50 searching and retrieval by proxying the
408      packages that are passed to it.  Init requests are sent to the
409      address specified in the <literal>VAL_PROXY</literal> otherInfo
410      attached to the request: this may have been specified by client,
411      or generated by a <literal>virt_db</literal> filter earlier in
412      the route.  Subsequent requests are sent to the same address,
413      which is remembered at Init time in a Session object.
414     </para>
415   </section>
416   </section>
417   
418   
419   <section>
420    <title>Future directions</title>
421   <para>
422     Some other filters that do not yet exist, but which would be
423     useful, are briefly described.  These may be added in future
424     releases (or may be created by third parties, as loadable
425     modules).
426    </para>
427
428    <variablelist>
429     <varlistentry>
430      <term><literal>frontend_cli</literal> (source)</term>
431     <listitem>
432       <para>
433        Command-line interface for generating requests.
434       </para>
435      </listitem>
436     </varlistentry>
437     <varlistentry>
438      <term><literal>srw2z3950</literal> (filter)</term>
439      <listitem>
440       <para>
441        Translate SRW requests into Z39.50 requests.
442      </para>
443      </listitem>
444     </varlistentry>
445     <varlistentry>
446      <term><literal>srw_client</literal> (sink)</term>
447      <listitem>
448       <para>
449        SRW searching and retrieval.
450       </para>
451      </listitem>
452     </varlistentry>
453     <varlistentry>
454      <term><literal>sru_client</literal> (sink)</term>
455      <listitem>
456       <para>
457        SRU searching and retrieval.
458       </para>
459      </listitem>
460     </varlistentry>
461     <varlistentry>
462      <term><literal>opensearch_client</literal> (sink)</term>
463      <listitem>
464       <para>
465        A9 OpenSearch searching and retrieval.
466       </para>
467      </listitem>
468     </varlistentry>
469    </variablelist>
470   </section>
471  </chapter>
472  
473  
474  
475  <chapter id="multidb">
476   <title>Virtual databases and multi-database searching</title>
477
478
479   <section>
480    <title>Introductory notes</title>
481    <para>
482     Two of Metaproxy's filters are concerned with multiple-database
483     operations.  Of these, <literal>virt_db</literal> can work alone
484     to control the routing of searches to one of a number of servers,
485     while <literal>multi</literal> can work with the output of
486     <literal>virt_db</literal> to perform multicast searching, merging
487     the results into a unified result-set.  The interaction between
488     these two filters is necessarily complex, reflecting the real
489     complexity of multicast searching in a protocol such as Z39.50
490     that separates initialisation from searching, with the database to
491     search known only during the latter operation.
492    </para>
493    <para>
494     ### Much, much more to say!
495    </para>
496   </section>
497  </chapter>
498
499
500
501  <chapter id="configuration">
502   <title>Configuration: the Metaproxy configuration file format</title>
503   
504   
505   <section>
506    <title>Introductory notes</title>
507    <para>
508     If Metaproxy is an interpreter providing operations on packages, then
509     its configuration file can be thought of as a program for that
510     interpreter.  Configuration is by means of a single file, the name
511     of which is supplied as the sole command-line argument to the
512     <command>yp2</command> program.
513    </para>
514    <para>
515     The configuration files are written in XML.  (But that's just an
516     implementation detail - they could just as well have been written
517     in YAML or Lisp-like S-expressions, or in a custom syntax.)
518    </para>
519    <para>
520     Since XML has been chosen, an XML schema,
521     <filename>config.xsd</filename>, is provided for validating
522     configuration files.  This file is supplied in the
523     <filename>etc</filename> directory of the Metaproxy distribution.  It
524     can be used by (among other tools) the <command>xmllint</command>
525     program supplied as part of the <literal>libxml2</literal>
526     distribution:
527    </para>
528    <screen>
529     xmllint --noout --schema etc/config.xsd my-config-file.xml
530    </screen>
531    <para>
532     (A recent version of <literal>libxml2</literal> is required, as
533     support for XML Schemas is a relatively recent addition.)
534    </para>
535   </section>
536   
537   <section>
538    <title>Overview of XML structure</title>
539    <para>
540     All elements and attributes are in the namespace
541     <ulink url="http://indexdata.dk/yp2/config/1"/>.
542      This is most easily achieved by setting the default namespace on
543      the top-level element, as here:
544    </para>
545    <screen>
546     &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
547    </screen>
548    <para>
549     The top-level element is &lt;yp2&gt;.  This contains a
550     &lt;start&gt; element, a &lt;filters&gt; element and a
551     &lt;routes&gt; element, in that order.  &lt;filters&gt; is
552     optional; the other two are mandatory.  All three are
553     non-repeatable.
554    </para>
555   <para>
556     The &lt;start&gt; element is empty, but carries a
557     <literal>route</literal> attribute, whose value is the name of
558     route at which to start running - analogouse to the name of the
559     start production in a formal grammar.
560    </para>
561   <para>
562     If present, &lt;filters&gt; contains zero or more &lt;filter&gt;
563     elements; filters carry a <literal>type</literal> attribute and
564     contain various elements that provide suitable configuration for
565     filters of that type.  The filter-specific elements are described
566     below.  Filters defined in this part of the file must carry an
567     <literal>id</literal> attribute so that they can be referenced
568     from elsewhere.
569    </para>
570    <para>
571     &lt;routes&gt; contains one or more &lt;route&gt; elements, each
572     of which must carry an <literal>id</literal> element.  One of the
573     routes must have the ID value that was specified as the start
574     route in the &lt;start&gt; element's <literal>route</literal>
575     attribute.  Each route contains zero or more &lt;filter&gt;
576     elements.  These are of two types.  They may be empty, but carry a
577     <literal>refid</literal> attribute whose value is the same as the
578     <literal>id</literal> of a filter previously defined in the
579     &lt;filters&gt; section.  Alternatively, a route within a filter
580     may omit the <literal>refid</literal> attribute, but contain
581     configuration elements similar to those used for filters defined
582     in the &lt;filters&gt; section.
583    </para>
584   </section>
585
586
587   <section>
588    <title>Filter configuration</title>
589    <para>
590     All &lt;filter&gt; elements have in common that they must carry a
591     <literal>type</literal> attribute whose value is one of the
592     supported ones, listed in the schema file and discussed below.  In
593     additional, &lt;filters&gt;s occurring the &lt;filters&gt; section
594     must have an <literal>id</literal> attribute, and those occurring
595     within a route must have either a <literal>refid</literal>
596     attribute referencing a previously defined filter or contain its
597     own configuration information.
598    </para>
599    <para>
600     In general, each filter recognises different configuration
601     elements within its element, as each filter has different
602     functionality.  These are as follows:
603    </para>
604
605    <section>
606     <title><literal>auth_simple</literal></title>
607     <screen>
608      &lt;filter type="auth_simple"&gt;
609      &lt;userRegister&gt;../etc/example.simple-auth&lt;/userRegister&gt;
610      &lt;/filter&gt;
611     </screen>
612    </section>
613
614    <section>
615     <title><literal>backend_test</literal></title>
616     <screen>
617      &lt;filter type="backend_test"/&gt;
618     </screen>
619    </section>
620
621    <section>
622     <title><literal>frontend_net</literal></title>
623     <screen>
624      &lt;filter type="frontend_net"&gt;
625      &lt;threads&gt;10&lt;/threads&gt;
626      &lt;port&gt;@:9000&lt;/port&gt;
627      &lt;/filter&gt;
628     </screen>
629    </section>
630
631    <section>
632     <title><literal>http_file</literal></title>
633     <screen>
634      &lt;filter type="http_file"&gt;
635      &lt;mimetypes&gt;/etc/mime.types&lt;/mimetypes&gt;
636      &lt;area&gt;
637      &lt;documentroot&gt;.&lt;/documentroot&gt;
638      &lt;prefix&gt;/etc&lt;/prefix&gt;
639      &lt;/area&gt;
640      &lt;/filter&gt;
641     </screen>
642    </section>
643
644    <section>
645     <title><literal>log</literal></title>
646     <screen>
647      &lt;filter type="log"&gt;
648      &lt;message&gt;B&lt;/message&gt;
649      &lt;/filter&gt;
650     </screen>
651    </section>
652
653    <section>
654     <title><literal>multi</literal></title>
655     <screen>
656      &lt;filter type="multi"/&gt;
657     </screen>
658    </section>
659
660    <section>
661     <title><literal>query_rewrite</literal></title>
662     <screen>
663      &lt;filter type="query_rewrite"&gt;
664      &lt;xslt&gt;pqf2pqf.xsl&lt;/xslt&gt;
665      &lt;/filter&gt;
666     </screen>
667    </section>
668
669    <section>
670     <title><literal>session_shared</literal></title>
671     <screen>
672      &lt;filter type="session_shared"&gt;
673      ### Not yet defined
674      &lt;/filter&gt;
675     </screen>
676    </section>
677
678    <section>
679     <title><literal>template</literal></title>
680     <screen>
681      &lt;filter type="template"/&gt;
682     </screen>
683    </section>
684
685    <section>
686     <title><literal>virt_db</literal></title>
687     <screen>
688      &lt;filter type="virt_db"&gt;
689      &lt;virtual&gt;
690      &lt;database&gt;loc&lt;/database&gt;
691      &lt;target&gt;z3950.loc.gov:7090/voyager&lt;/target&gt;
692      &lt;/virtual&gt;
693      &lt;virtual&gt;
694      &lt;database&gt;idgils&lt;/database&gt;
695      &lt;target&gt;indexdata.dk/gils&lt;/target&gt;
696      &lt;/virtual&gt;
697      &lt;/filter&gt;
698     </screen>
699    </section>
700
701    <section>
702     <title><literal>z3950_client</literal></title>
703     <screen>
704      &lt;filter type="z3950_client"&gt;
705      &lt;timeout&gt;30&lt;/timeout&gt;
706      &lt;/filter&gt;
707     </screen>
708    </section>
709   </section>
710  </chapter>
711
712
713
714  <chapter id="moduleref">
715   <title>Module Reference</title>
716   <para>
717    The material in this chapter includes the man pages material
718   </para>
719   &manref;
720  </chapter>
721
722  <chapter id="extensions">
723   <title>Writing extensions for Metaproxy</title>
724   <para>###</para>
725  </chapter>
726
727  <chapter id="classes">
728   <title>Classes in the Metaproxy source code</title>
729
730
731   <section>
732    <title>Introductory notes</title>
733    <para>
734     <emphasis>Stop!  Do not read this!</emphasis>
735     You won't enjoy it at all.
736    </para>
737    <para>
738     This chapter contains documentation of the Metaproxy source code, and is
739     of interest only to maintainers and developers.  If you need to
740     change Metaproxy's behaviour or write a new filter, then you will most
741     likely find this chapter helpful.  Otherwise it's a waste of your
742     good time.  Seriously: go and watch a film or something.
743     <citetitle>This is Spinal Tap</citetitle> is particularly good.
744    </para>
745    <para>
746     Still here?  OK, let's continue.
747    </para>
748    <para>
749     In general, classes seem to be named big-endianly, so that
750     <literal>FactoryFilter</literal> is not a filter that filters
751     factories, but a factory that produces filters; and
752     <literal>FactoryStatic</literal> is a factory for the statically
753     registered filters (as opposed to those that are dynamically
754     loaded).
755    </para>
756   </section>
757
758   <section>
759    <title>Individual classes</title>
760    <para>
761     The classes making up the Metaproxy application are here listed by
762     class-name, with the names of the source files that define them in
763     parentheses.
764    </para>
765
766    <section>
767     <title><literal>mp::FactoryFilter</literal>
768      (<filename>factory_filter.cpp</filename>)</title>
769     <para>
770      A factory class that exists primarily to provide the
771      <literal>create()</literal> method, which takes the name of a
772      filter class as its argument and returns a new filter of that
773      type.  To enable this, the factory must first be populated by
774      calling <literal>add_creator()</literal> for static filters (this
775      is done by the <literal>FactoryStatic</literal> class, see below)
776      and <literal>add_creator_dyn()</literal> for filters loaded
777      dynamically.
778     </para>
779    </section>
780
781    <section>
782     <title><literal>mp::FactoryStatic</literal>
783      (<filename>factory_static.cpp</filename>)</title>
784     <para>
785      A subclass of <literal>FactoryFilter</literal> which is
786      responsible for registering all the statically defined filter
787      types.  It does this by knowing about all those filters'
788      structures, which are listed in its constructor.  Merely
789      instantiating this class registers all the static classes.  It is
790      for the benefit of this class that <literal>struct
791       yp2_filter_struct</literal> exists, and that all the filter
792      classes provide a static object of that type.
793     </para>
794    </section>
795
796    <section>
797     <title><literal>mp::filter::Base</literal>
798      (<filename>filter.cpp</filename>)</title>
799     <para>
800      The virtual base class of all filters.  The filter API is, on the
801      surface at least, extremely simple: two methods.
802      <literal>configure()</literal> is passed a DOM tree representing
803      that part of the configuration file that pertains to this filter
804      instance, and is expected to walk that tree extracting relevant
805      information.  And <literal>process()</literal> processes a
806      package (see below).  That surface simplicitly is a bit
807      misleading, as <literal>process()</literal> needs to know a lot
808      about the <literal>Package</literal> class in order to do
809      anything useful.
810     </para>
811    </section>
812
813    <section>
814     <title><literal>mp::filter::AuthSimple</literal>,
815      <literal>Backend_test</literal>, etc.
816      (<filename>filter_auth_simple.cpp</filename>,
817      <filename>filter_backend_test.cpp</filename>, etc.)</title>
818     <para>
819      Individual filters.  Each of these is implemented by a header and
820      a source file, named <filename>filter_*.hpp</filename> and
821      <filename>filter_*.cpp</filename> respectively.  All the header
822      files should be pretty much identical, in that they declare the
823      class, including a private <literal>Rep</literal> class and a
824      member pointer to it, and the two public methods.  The only extra
825      information in any filter header is additional private types and
826      members (which should really all be in the <literal>Rep</literal>
827      anyway) and private methods (which should also remain known only
828      to the source file, but C++'s brain-damaged design requires this
829      dirty laundry to be exhibited in public.  Thanks, Bjarne!)
830     </para>
831     <para>
832      The source file for each filter needs to supply:
833     </para>
834     <itemizedlist>
835      <listitem>
836       <para>
837        A definition of the private <literal>Rep</literal> class.
838       </para>
839      </listitem>
840      <listitem>
841       <para>
842        Some boilerplate constructors and destructors.
843       </para>
844      </listitem>
845      <listitem>
846       <para>
847        A <literal>configure()</literal> method that uses the
848        appropriate XML fragment.
849       </para>
850      </listitem>
851      <listitem>
852       <para>
853        Most important, the <literal>process()</literal> method that
854        does all the actual work.
855       </para>
856      </listitem>
857     </itemizedlist>
858    </section>
859
860    <section>
861     <title><literal>mp::Package</literal>
862      (<filename>package.cpp</filename>)</title>
863     <para>
864      Represents a package on its way through the series of filters
865      that make up a route.  This is essentially a Z39.50 or SRU APDU
866      together with information about where it came from, which is
867      modified as it passes through the various filters.
868     </para>
869    </section>
870
871    <section>
872     <title><literal>mp::Pipe</literal>
873      (<filename>pipe.cpp</filename>)</title>
874     <para>
875      This class provides a compatibility layer so that we have an IPC
876      mechanism that works the same under Unix and Windows.  It's not
877      particularly exciting.
878     </para>
879    </section>
880
881    <section>
882     <title><literal>mp::RouterChain</literal>
883      (<filename>router_chain.cpp</filename>)</title>
884     <para>
885      ###
886     </para>
887    </section>
888
889    <section>
890     <title><literal>mp::RouterFleXML</literal>
891      (<filename>router_flexml.cpp</filename>)</title>
892     <para>
893      ###
894     </para>
895    </section>
896
897    <section>
898     <title><literal>mp::Session</literal>
899      (<filename>session.cpp</filename>)</title>
900     <para>
901      ###
902     </para>
903    </section>
904
905    <section>
906     <title><literal>mp::ThreadPoolSocketObserver</literal>
907      (<filename>thread_pool_observer.cpp</filename>)</title>
908     <para>
909      ###
910     </para>
911    </section>
912
913    <section>
914     <title><literal>mp::util</literal>
915      (<filename>util.cpp</filename>)</title>
916     <para>
917      A namespace of various small utility functions and classes,
918      collected together for convenience.  Most importantly, includes
919      the <literal>mp::util::odr</literal> class, a wrapper for YAZ's
920      ODR facilities.
921     </para>
922    </section>
923
924    <section>
925     <title><literal>mp::xml</literal>
926      (<filename>xmlutil.cpp</filename>)</title>
927     <para>
928      A namespace of various XML utility functions and classes,
929      collected together for convenience.
930     </para>
931    </section>
932   </section>
933
934
935   <section>
936    <title>Other Source Files</title>
937    <para>
938     In addition to the Metaproxy source files that define the classes
939     described above, there are a few additional files which are
940     briefly described here:
941    </para>
942    <variablelist>
943     <varlistentry>
944      <term><literal>metaproxy_prog.cpp</literal></term>
945      <listitem>
946       <para>
947        The main function of the <command>yp2</command> program.
948       </para>
949      </listitem>
950     </varlistentry>
951     <varlistentry>
952      <term><literal>ex_router_flexml.cpp</literal></term>
953      <listitem>
954       <para>
955        Identical to <literal>metaproxy_prog.cpp</literal>: it's not clear why.
956       </para>
957      </listitem>
958     </varlistentry>
959     <varlistentry>
960      <term><literal>test_*.cpp</literal></term>
961      <listitem>
962       <para>
963        Unit-tests for various modules.
964       </para>
965      </listitem>
966     </varlistentry>
967    </variablelist>
968    <para>
969     ### Still to be described:
970     <literal>ex_filter_frontend_net.cpp</literal>,
971     <literal>filter_dl.cpp</literal>,
972     <literal>plainfile.cpp</literal>,
973     <literal>tstdl.cpp</literal>.
974    </para>
975    
976    
977    <!-- Epilogue -->
978    <para>
979     --
980    </para>
981    <screen>
982     <!-- This is just a lame way to get some vertical whitespace at
983     the end of the document -->
984     
985     
986     
987     
988    </screen>
989   </section>
990  </chapter>
991
992  <!-- Keep this comment at the end of the file
993  Local variables:
994  mode: sgml
995  sgml-omittag:t
996  sgml-shorttag:t
997  sgml-minimize-attributes:nil
998  sgml-always-quote-attributes:t
999  sgml-indent-step:1
1000  sgml-indent-data:t
1001  sgml-parent-document: "main.xml"
1002  sgml-local-catalogs: nil
1003  sgml-namecase-general:t
1004  nxml-child-indent: 1
1005  End:
1006  -->