03032af0ef8dd490f248b1ff91e18a5fa808400e
[metaproxy-moved-to-github.git] / doc / book.xml
1 <!-- $Id: book.xml,v 1.1 2006-03-16 12:03:39 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  <copyright>
8   <year>2006</year>
9   <holder>Index Data</holder>
10  </copyright>
11  <abstract>
12   <simpara>
13    ###
14    Metaproxy is ... in need of description :-)
15   </simpara>
16  </abstract>
17  </bookinfo>
18  
19
20
21  <chapter id="introduction">
22  <title>Introduction</title>
23
24
25  <section>
26   <title>Overview</title>
27   <para>
28    <ulink url="http://indexdata.dk/metaproxy/">Metaproxy</ulink>
29    is ..
30   </para>
31   <para>
32    ### We should probably consider saying a little more by way of
33    introduction.
34   </para>
35  </section>
36  </chapter>
37
38
39
40  <chapter id="filters">
41  <title>Filters</title>
42
43
44  <section>
45   <title>Introductory notes</title>
46   <para>
47    It's useful to think of Metaproxy as an interpreter providing a small
48    number of primitives and operations, but operating on a very
49    complex data type, namely the ``package''.
50   </para>
51   <para>
52    A package represents a Z39.50 or SRW/U request (whether for Init,
53    Search, Scan, etc.)  together with information about where it came
54    from.  Packages are created by front-end filters such as
55    <literal>frontend_net</literal> (see below), which reads them from
56    the network; other front-end filters are possible.  They then pass
57    along a route consisting of a sequence of filters, each of which
58    transforms the package and may also have side-effects such as
59    generating logging.  Eventually, the route will yield a response,
60    which is sent back to the origin.
61   </para>
62   <para>
63    There are many kinds of filter: some that are defined statically
64    as part of Metaproxy, and other that may be provided by third parties
65    and dynamically loaded.  They all conform to the same simple API
66    of essentially two methods: <function>configure()</function> is
67    called at startup time, and is passed a DOM tree representing that
68    part of the configuration file that pertains to this filter
69    instance: it is expected to walk that tree extracting relevant
70    information; and <function>process()</function> is called every
71    time the filter has to processes a package.
72   </para>
73   <para>
74    While all filters provide the same API, there are different modes
75    of functionality.  Some filters are sources: they create
76    packages
77    (<literal>frontend_net</literal>);
78    others are sinks: they consume packages and return a result
79    (<literal>z3950_client</literal>,
80    <literal>backend_test</literal>,
81    <literal>http_file</literal>);
82    the others are true filters, that read, process and pass on the
83    packages they are fed
84    (<literal>auth_simple</literal>,
85    <literal>log</literal>,
86    <literal>multi</literal>,
87    <literal>session_shared</literal>,
88    <literal>template</literal>,
89    <literal>virt_db</literal>).
90   </para>
91  </section>
92
93
94  <section>
95   <title>Individual filters</title>
96   <para>
97    The filters are here named by the string that is used as the
98    <literal>type</literal> attribute of a
99    <literal>&lt;filter&gt;</literal> element in the configuration
100    file to request them, with the name of the class that implements
101    them in parentheses.
102   </para>
103
104   <section>
105    <title><literal>auth_simple</literal>
106     (mp::filter::AuthSimple)</title>
107    <para>
108     Simple authentication and authorisation.  The configuration
109     specifies the name of a file that is the user register, which
110     lists <varname>username</varname>:<varname>password</varname>
111     pairs, one per line, colon separated. When a session begins, it
112     is rejected unless username and passsword are supplied, and match
113     a pair in the register.
114    </para>
115    <para>
116     ### discuss authorisation phase
117    </para>
118   </section>
119
120   <section>
121    <title><literal>backend_test</literal>
122     (mp::filter::Backend_test)</title>
123    <para>
124     A sink that provides dummy responses in the manner of the
125     <literal>yaz-ztest</literal> Z39.50 server.  This is useful only
126     for testing.
127    </para>
128   </section>
129
130   <section>
131    <title><literal>frontend_net</literal>
132     (mp::filter::FrontendNet)</title>
133    <para>
134     A source that accepts Z39.50 and SRW connections from a port
135     specified in the configuration, reads protocol units, and
136     feeds them into the next filter, eventually returning the
137     result to the origin.
138    </para>
139   </section>
140
141   <section>
142    <title><literal>http_file</literal>
143     (mp::filter::HttpFile)</title>
144    <para>
145     A sink that returns the contents of files from the local
146     filesystem in response to HTTP requests.  (Yes, Virginia, this
147     does mean that Metaproxy is also a Web-server in its spare time.  So
148     far it does not contain either an email-reader or a Lisp
149     interpreter, but that day is surely coming.)
150    </para>
151   </section>
152
153   <section>
154    <title><literal>log</literal>
155     (mp::filter::Log)</title>
156    <para>
157     Writes logging information to standard output, and passes on
158     the package unchanged.
159    </para>
160   </section>
161
162   <section>
163    <title><literal>multi</literal>
164     (mp::filter::Multi)</title>
165    <para>
166     Performs multicast searching.  See the extended discussion of
167     multi-database searching below.
168    </para>
169   </section>
170
171   <section>
172    <title><literal>session_shared</literal>
173     (mp::filter::SessionShared)</title>
174    <para>
175     When this is finished, it will implement global sharing of
176     result sets (i.e. between threads and therefore between
177     clients), but it's not yet done.
178    </para>
179   </section>
180
181   <section>
182    <title><literal>template</literal>
183     (mp::filter::Template)</title>
184    <para>
185     Does nothing at all, merely passing the packet on.  (Maybe it
186     should be called <literal>nop</literal> or
187     <literal>passthrough</literal>?)  This exists not to be used, but
188     to be copied - to become the skeleton of new filters as they are
189     written.
190    </para>
191   </section>
192
193   <section>
194    <title><literal>virt_db</literal>
195     (mp::filter::Virt_db)</title>
196    <para>
197     Performs virtual database selection.  See the extended discussion
198     of virtual databases below.
199    </para>
200   </section>
201
202   <section>
203    <title><literal>z3950_client</literal>
204     (mp::filter::Z3950Client)</title>
205    <para>
206     Performs Z39.50 searching and retrieval by proxying the
207     packages that are passed to it.  Init requests are sent to the
208     address specified in the <literal>VAL_PROXY</literal> otherInfo
209     attached to the request: this may have been specified by client,
210     or generated by a <literal>virt_db</literal> filter earlier in
211     the route.  Subsequent requests are sent to the same address,
212     which is remembered at Init time in a Session object.
213    </para>
214   </section>
215  </section>
216
217
218  <section>
219   <title>Future directions</title>
220   <para>
221    Some other filters that do not yet exist, but which would be
222    useful, are briefly described.  These may be added in future
223    releases.
224   </para>
225
226   <variablelist>
227    <varlistentry>
228     <term><literal>frontend_cli</literal> (source)</term>
229     <listitem>
230      <para>
231       Command-line interface for generating requests.
232      </para>
233     </listitem>
234    </varlistentry>
235    <varlistentry>
236     <term><literal>srw2z3950</literal> (filter)</term>
237     <listitem>
238      <para>
239       Translate SRW requests into Z39.50 requests.
240      </para>
241     </listitem>
242    </varlistentry>
243    <varlistentry>
244     <term><literal>srw_client</literal> (sink)</term>
245     <listitem>
246      <para>
247       SRW searching and retrieval.
248      </para>
249     </listitem>
250    </varlistentry>
251    <varlistentry>
252     <term><literal>sru_client</literal> (sink)</term>
253     <listitem>
254      <para>
255       SRU searching and retrieval.
256      </para>
257     </listitem>
258    </varlistentry>
259    <varlistentry>
260     <term><literal>opensearch_client</literal> (sink)</term>
261     <listitem>
262      <para>
263       A9 OpenSearch searching and retrieval.
264      </para>
265     </listitem>
266    </varlistentry>
267   </variablelist>
268  </section>
269  </chapter>
270
271
272
273  <chapter id="configuration">
274  <title>Configuration: the Metaproxy configuration file format</title>
275
276
277  <section>
278   <title>Introductory notes</title>
279   <para>
280    If Metaproxy is an interpreter providing operations on packages, then
281    its configuration file can be thought of as a program for that
282    interpreter.  Configuration is by means of a single file, the name
283    of which is supplied as the sole command-line argument to the
284    <command>yp2</command> program.
285   </para>
286   <para>
287    The configuration files are written in XML.  (But that's just an
288    implementation detail - they could just as well have been written
289    in YAML or Lisp-like S-expressions, or in a custom syntax.)
290   </para>
291   <para>
292    Since XML has been chosen, an XML schema,
293    <filename>config.xsd</filename>, is provided for validating
294    configuration files.  This file is supplied in the
295    <filename>etc</filename> directory of the Metaproxy distribution.  It
296    can be used by (among other tools) the <command>xmllint</command>
297    program supplied as part of the <literal>libxml2</literal>
298    distribution:
299   </para>
300   <screen>
301    xmllint --noout --schema etc/config.xsd my-config-file.xml
302   </screen>
303   <para>
304    (A recent version of <literal>libxml2</literal> is required, as
305    support for XML Schemas is a relatively recent addition.)
306   </para>
307  </section>
308
309  <section>
310   <title>Overview of XML structure</title>
311   <para>
312    All elements and attributes are in the namespace
313    <ulink url="http://indexdata.dk/yp2/config/1"/>.
314     This is most easily achieved by setting the default namespace on
315     the top-level element, as here:
316   </para>
317   <screen>
318    &lt;yp2 xmlns="http://indexdata.dk/yp2/config/1"&gt;
319   </screen>
320   <para>
321    The top-level element is &lt;yp2&gt;.  This contains a
322    &lt;start&gt; element, a &lt;filters&gt; element and a
323    &lt;routes&gt; element, in that order.  &lt;filters&gt; is
324    optional; the other two are mandatory.  All three are
325    non-repeatable.
326   </para>
327   <para>
328    The &lt;start&gt; element is empty, but carries a
329    <literal>route</literal> attribute, whose value is the name of
330    route at which to start running - analogouse to the name of the
331    start production in a formal grammar.
332   </para>
333   <para>
334    If present, &lt;filters&gt; contains zero or more &lt;filter&gt;
335    elements; filters carry a <literal>type</literal> attribute and
336    contain various elements that provide suitable configuration for
337    filters of that type.  The filter-specific elements are described
338    below.  Filters defined in this part of the file must carry an
339    <literal>id</literal> attribute so that they can be referenced
340    from elsewhere.
341   </para>
342   <para>
343    &lt;routes&gt; contains one or more &lt;route&gt; elements, each
344    of which must carry an <literal>id</literal> element.  One of the
345    routes must have the ID value that was specified as the start
346    route in the &lt;start&gt; element's <literal>route</literal>
347    attribute.  Each route contains zero or more &lt;filter&gt;
348    elements.  These are of two types.  They may be empty, but carry a
349    <literal>refid</literal> attribute whose value is the same as the
350    <literal>id</literal> of a filter previously defined in the
351    &lt;filters&gt; section.  Alternatively, a route within a filter
352    may omit the <literal>refid</literal> attribute, but contain
353    configuration elements similar to those used for filters defined
354    in the &lt;filters&gt; section.
355   </para>
356  </section>
357
358
359  <section>
360   <title>Filter configuration</title>
361   <para>
362    All &lt;filter&gt; elements have in common that they must carry a
363    <literal>type</literal> attribute whose value is one of the
364    supported ones, listed in the schema file and discussed below.  In
365    additional, &lt;filters&gt;s occurring the &lt;filters&gt; section
366    must have an <literal>id</literal> attribute, and those occurring
367    within a route must have either a <literal>refid</literal>
368    attribute referencing a previously defined filter or contain its
369    own configuration information.
370   </para>
371   <para>
372    In general, each filter recognises different configuration
373    elements within its element, as each filter has different
374    functionality.  These are as follows:
375   </para>
376
377   <section>
378    <title><literal>auth_simple</literal></title>
379    <screen>
380     &lt;filter type="auth_simple"&gt;
381     &lt;userRegister&gt;../etc/example.simple-auth&lt;/userRegister&gt;
382     &lt;/filter&gt;
383    </screen>
384   </section>
385
386   <section>
387    <title><literal>backend_test</literal></title>
388    <screen>
389     &lt;filter type="backend_test"/&gt;
390    </screen>
391   </section>
392
393   <section>
394    <title><literal>frontend_net</literal></title>
395    <screen>
396     &lt;filter type="frontend_net"&gt;
397     &lt;threads&gt;10&lt;/threads&gt;
398     &lt;port&gt;@:9000&lt;/port&gt;
399     &lt;/filter&gt;
400    </screen>
401   </section>
402
403   <section>
404    <title><literal>http_file</literal></title>
405    <screen>
406     &lt;filter type="http_file"&gt;
407     &lt;mimetypes&gt;/etc/mime.types&lt;/mimetypes&gt;
408     &lt;area&gt;
409     &lt;documentroot&gt;.&lt;/documentroot&gt;
410     &lt;prefix&gt;/etc&lt;/prefix&gt;
411     &lt;/area&gt;
412     &lt;/filter&gt;
413    </screen>
414   </section>
415
416   <section>
417    <title><literal>log</literal></title>
418    <screen>
419     &lt;filter type="log"&gt;
420     &lt;message&gt;B&lt;/message&gt;
421     &lt;/filter&gt;
422    </screen>
423   </section>
424
425   <section>
426    <title><literal>multi</literal></title>
427    <screen>
428     &lt;filter type="multi"/&gt;
429    </screen>
430   </section>
431
432   <section>
433    <title><literal>session_shared</literal></title>
434    <screen>
435     &lt;filter type="session_shared"&gt;
436     ### Not yet defined
437     &lt;/filter&gt;
438    </screen>
439   </section>
440
441   <section>
442    <title><literal>template</literal></title>
443    <screen>
444     &lt;filter type="template"/&gt;
445    </screen>
446   </section>
447
448   <section>
449    <title><literal>virt_db</literal></title>
450    <screen>
451     &lt;filter type="virt_db"&gt;
452     &lt;virtual&gt;
453     &lt;database&gt;loc&lt;/database&gt;
454     &lt;target&gt;z3950.loc.gov:7090/voyager&lt;/target&gt;
455     &lt;/virtual&gt;
456     &lt;virtual&gt;
457     &lt;database&gt;idgils&lt;/database&gt;
458     &lt;target&gt;indexdata.dk/gils&lt;/target&gt;
459     &lt;/virtual&gt;
460     &lt;/filter&gt;
461    </screen>
462   </section>
463
464   <section>
465    <title><literal>z3950_client</literal></title>
466    <screen>
467     &lt;filter type="z3950_client"&gt;
468     &lt;timeout&gt;30&lt;/timeout&gt;
469     &lt;/filter&gt;
470    </screen>
471   </section>
472  </section>
473  </chapter>
474
475
476
477  <chapter id="multidb">
478  <title>Virtual database as multi-database searching</title>
479
480
481  <section>
482   <title>Introductory notes</title>
483   <para>
484    Two of Metaproxy's filters are concerned with multiple-database
485    operations.  Of these, <literal>virt_db</literal> can work alone
486    to control the routing of searches to one of a number of servers,
487    while <literal>multi</literal> can work with the output of
488    <literal>virt_db</literal> to perform multicast searching, merging
489    the results into a unified result-set.  The interaction between
490    these two filters is necessarily complex, reflecting the real
491    complexity of multicast searching in a protocol such as Z39.50
492    that separates initialisation from searching, with the database to
493    search known only during the latter operation.
494   </para>
495   <para>
496    ### Much, much more to say!
497   </para>
498  </section>
499  </chapter>
500
501
502
503  <chapter id="classes">
504  <title>Classes in the Metaproxy source code</title>
505
506
507  <section>
508   <title>Introductory notes</title>
509   <para>
510    <emphasis>Stop!  Do not read this!</emphasis>
511    You won't enjoy it at all.
512   </para>
513   <para>
514    This chapter contains documentation of the Metaproxy source code, and is
515    of interest only to maintainers and developers.  If you need to
516    change Metaproxy's behaviour or write a new filter, then you will most
517    likely find this chapter helpful.  Otherwise it's a waste of your
518    good time.  Seriously: go and watch a film or something.
519    <citetitle>This is Spinal Tap</citetitle> is particularly good.
520   </para>
521   <para>
522    Still here?  OK, let's continue.
523   </para>
524   <para>
525    In general, classes seem to be named big-endianly, so that
526    <literal>FactoryFilter</literal> is not a filter that filters
527    factories, but a factory that produces filters; and
528    <literal>FactoryStatic</literal> is a factory for the statically
529    registered filters (as opposed to those that are dynamically
530    loaded).
531   </para>
532  </section>
533
534  <section>
535   <title>Individual classes</title>
536   <para>
537    The classes making up the Metaproxy application are here listed by
538    class-name, with the names of the source files that define them in
539    parentheses.
540   </para>
541
542   <section>
543    <title><literal>mp::FactoryFilter</literal>
544     (<filename>factory_filter.cpp</filename>)</title>
545    <para>
546     A factory class that exists primarily to provide the
547     <literal>create()</literal> method, which takes the name of a
548     filter class as its argument and returns a new filter of that
549     type.  To enable this, the factory must first be populated by
550     calling <literal>add_creator()</literal> for static filters (this
551     is done by the <literal>FactoryStatic</literal> class, see below)
552     and <literal>add_creator_dyn()</literal> for filters loaded
553     dynamically.
554    </para>
555   </section>
556
557   <section>
558    <title><literal>mp::FactoryStatic</literal>
559     (<filename>factory_static.cpp</filename>)</title>
560    <para>
561     A subclass of <literal>FactoryFilter</literal> which is
562     responsible for registering all the statically defined filter
563     types.  It does this by knowing about all those filters'
564     structures, which are listed in its constructor.  Merely
565     instantiating this class registers all the static classes.  It is
566     for the benefit of this class that <literal>struct
567      yp2_filter_struct</literal> exists, and that all the filter
568     classes provide a static object of that type.
569    </para>
570   </section>
571
572   <section>
573    <title><literal>mp::filter::Base</literal>
574     (<filename>filter.cpp</filename>)</title>
575    <para>
576     The virtual base class of all filters.  The filter API is, on the
577     surface at least, extremely simple: two methods.
578     <literal>configure()</literal> is passed a DOM tree representing
579     that part of the configuration file that pertains to this filter
580     instance, and is expected to walk that tree extracting relevant
581     information.  And <literal>process()</literal> processes a
582     package (see below).  That surface simplicitly is a bit
583     misleading, as <literal>process()</literal> needs to know a lot
584     about the <literal>Package</literal> class in order to do
585     anything useful.
586    </para>
587   </section>
588
589   <section>
590    <title><literal>mp::filter::AuthSimple</literal>,
591     <literal>Backend_test</literal>, etc.
592     (<filename>filter_auth_simple.cpp</filename>,
593     <filename>filter_backend_test.cpp</filename>, etc.)</title>
594    <para>
595     Individual filters.  Each of these is implemented by a header and
596     a source file, named <filename>filter_*.hpp</filename> and
597     <filename>filter_*.cpp</filename> respectively.  All the header
598     files should be pretty much identical, in that they declare the
599     class, including a private <literal>Rep</literal> class and a
600     member pointer to it, and the two public methods.  The only extra
601     information in any filter header is additional private types and
602     members (which should really all be in the <literal>Rep</literal>
603     anyway) and private methods (which should also remain known only
604     to the source file, but C++'s brain-damaged design requires this
605     dirty laundry to be exhibited in public.  Thanks, Bjarne!)
606    </para>
607    <para>
608     The source file for each filter needs to supply:
609    </para>
610    <itemizedlist>
611     <listitem>
612      <para>
613       A definition of the private <literal>Rep</literal> class.
614      </para>
615     </listitem>
616     <listitem>
617      <para>
618       Some boilerplate constructors and destructors.
619      </para>
620     </listitem>
621     <listitem>
622      <para>
623       A <literal>configure()</literal> method that uses the
624       appropriate XML fragment.
625      </para>
626     </listitem>
627     <listitem>
628      <para>
629       Most important, the <literal>process()</literal> method that
630       does all the actual work.
631      </para>
632     </listitem>
633    </itemizedlist>
634   </section>
635
636   <section>
637    <title><literal>mp::Package</literal>
638     (<filename>package.cpp</filename>)</title>
639    <para>
640     Represents a package on its way through the series of filters
641     that make up a route.  This is essentially a Z39.50 or SRU APDU
642     together with information about where it came from, which is
643     modified as it passes through the various filters.
644    </para>
645   </section>
646
647   <section>
648    <title><literal>mp::Pipe</literal>
649     (<filename>pipe.cpp</filename>)</title>
650    <para>
651     This class provides a compatibility layer so that we have an IPC
652     mechanism that works the same under Unix and Windows.  It's not
653     particularly exciting.
654    </para>
655   </section>
656
657   <section>
658    <title><literal>mp::RouterChain</literal>
659     (<filename>router_chain.cpp</filename>)</title>
660    <para>
661     ###
662    </para>
663   </section>
664
665   <section>
666    <title><literal>mp::RouterFleXML</literal>
667     (<filename>router_flexml.cpp</filename>)</title>
668    <para>
669     ###
670    </para>
671   </section>
672
673   <section>
674    <title><literal>mp::Session</literal>
675     (<filename>session.cpp</filename>)</title>
676    <para>
677     ###
678    </para>
679   </section>
680
681   <section>
682    <title><literal>mp::ThreadPoolSocketObserver</literal>
683     (<filename>thread_pool_observer.cpp</filename>)</title>
684    <para>
685     ###
686    </para>
687   </section>
688
689   <section>
690    <title><literal>mp::util</literal>
691     (<filename>util.cpp</filename>)</title>
692    <para>
693     A namespace of various small utility functions and classes,
694     collected together for convenience.  Most importantly, includes
695     the <literal>mp::util::odr</literal> class, a wrapper for YAZ's
696     ODR facilities.
697    </para>
698   </section>
699
700   <section>
701    <title><literal>mp::xml</literal>
702     (<filename>xmlutil.cpp</filename>)</title>
703    <para>
704     A namespace of various XML utility functions and classes,
705     collected together for convenience.
706    </para>
707   </section>
708  </section>
709
710
711  <section>
712   <title>Other Source Files</title>
713   <para>
714    In addition to the Metaproxy source files that define the classes
715    described above, there are a few additional files which are
716    briefly described here:
717   </para>
718   <variablelist>
719    <varlistentry>
720     <term><literal>metaproxy_prog.cpp</literal></term>
721     <listitem>
722      <para>
723       The main function of the <command>yp2</command> program.
724      </para>
725     </listitem>
726    </varlistentry>
727    <varlistentry>
728     <term><literal>ex_router_flexml.cpp</literal></term>
729     <listitem>
730      <para>
731       Identical to <literal>metaproxy_prog.cpp</literal>: it's not clear why.
732      </para>
733     </listitem>
734    </varlistentry>
735    <varlistentry>
736     <term><literal>test_*.cpp</literal></term>
737     <listitem>
738      <para>
739       Unit-tests for various modules.
740      </para>
741     </listitem>
742    </varlistentry>
743   </variablelist>
744   <para>
745    ### Still to be described:
746    <literal>ex_filter_frontend_net.cpp</literal>,
747    <literal>filter_dl.cpp</literal>,
748    <literal>plainfile.cpp</literal>,
749    <literal>tstdl.cpp</literal>.
750   </para>
751   
752   
753   <!-- Epilogue -->
754   <para>
755    --
756   </para>
757   <screen>
758    <!-- This is just a lame way to get some vertical whitespace at
759    the end of the document -->
760    
761    
762    
763    
764   </screen>
765  </section>
766  </chapter>
767
768 <!-- Keep this comment at the end of the file
769 Local variables:
770 mode: sgml
771 sgml-omittag:t
772 sgml-shorttag:t
773 sgml-minimize-attributes:nil
774 sgml-always-quote-attributes:t
775 sgml-indent-step:1
776 sgml-indent-data:t
777 sgml-parent-document:yp2.xml
778 sgml-local-catalogs: nil
779 sgml-namecase-general:t
780 End:
781 -->