-<!-- $Id: frontend.xml,v 1.7 2001-10-24 20:12:36 adam Exp $ -->
+<!-- $Id: frontend.xml,v 1.17 2003-04-28 21:02:16 adam Exp $ -->
<chapter id="server"><title>Generic server</title>
<sect1><title>Introduction</title>
-
+
<para>
If you aren't into documentation, a good way to learn how the
back end interface works is to look at the <filename>backend.h</filename>
<para>
If you have a database system that you would like to make available by
- means of Z39.50, &yaz; basically offers your two options. You
+ means of Z39.50 or SRW, &yaz; basically offers your two options. You
can use the APIs provided by the &asn;, &odr;, and &comstack;
modules to
create and decode PDUs, and exchange them with a client.
too many structural changes in existing applications.
</para>
</note>
+
+ <note>
+ <para>
+ The &yaz; server does not support XCQL.
+ </para>
+ </note>
</sect1>
<sect1 id="server.frontend"><title>The Database Frontend</title>
The backend API consists of a small number of function handlers and
structure definitions. You are required to provide the
<function>main()</function> routine for the server (which can be
- quite simple), as well as a set of handlers to match each of the prototypes.
+ quite simple), as well as a set of handlers to match each of the
+ prototypes.
The interface functions that you write can use any mechanism you like
to communicate with your database system: You might link the whole
thing together with your database application and access it by
<varlistentry><term>
<literal>enum oid_proto default_proto;</literal></term>
- <listitem><para>Either <literal>PROTO_SR</literal> or
- <literal>PROTO_Z3950</literal>.
+ <listitem><para>Either <literal>PROTO_Z3950</literal> or
+ <literal>PROTO_SR</literal>.
Default is <literal>PROTO_Z39_50</literal>.
</para></listitem></varlistentry>
<varlistentry><term>
<literal>int idle_timeout;</literal></term>
- <listitem><para>Maximum session idletime, in minutes. Zero indicates
+ <listitem><para>Maximum session idle-time, in minutes. Zero indicates
no (infinite) timeout. Default is 120 minutes.
</para></listitem></varlistentry>
<function>bend_init</function> handler is passed in the call to
<function>statserv_start</function>.
</para>
+
+ <para>
+ This handler is also called when operating in SRW/SRU mode - when
+ a connection has been made (even though SRW/SRU does not offer
+ this service).
+ </para>
+
<para>
Unlike previous versions of YAZ, the <function>bend_init</function> also
serves as a handler that defines the Z39.50 services that the backend
Z_ReferenceId *referenceId;/* reference ID */
char *peer_name; /* dns host of peer (client) */
+ char *implementation_id;
char *implementation_name;
char *implementation_version;
int (*bend_sort) (void *handle, bend_sort_rr *rr);
int (*bend_delete)(void *handle, bend_delete_rr *rr);
int (*bend_scan)(void *handle, bend_scan_rr *rr);
int (*bend_segment)(void *handle, bend_segment_rr *rr);
+
+ ODR decode; /* decoding stream */
+ /* character set and language negotiation - see include/yaz/z-charneg.h */
+ Z_CharSetandLanguageNegotiation *charneg_request;
+ Z_External *charneg_response;
} bend_initrequest;
typedef struct bend_initresult
<para>
The members <literal>peer_name</literal>,
+ <literal>implementation_id</literal>,
<literal>implementation_name</literal> and
- <literal>implementation_version</literal> holds DNS of client, name
+ <literal>implementation_version</literal> holds
+ DNS of client, ID of implementor, name
of client (Z39.50) implementation - and version.
</para>
int errcode; /* 0==OK */
char *errstring; /* system error string or NULL */
} bend_search_rr;
-
</synopsis>
<para>
The <function>bend_search</function> handler is a fairly close
- approximation of a protocol Search Request - and Response PDUs
+ approximation of a protocol Z39.50 Search Request - and Response PDUs
The <literal>setname</literal> is the resultSetName from the protocol.
You are required to establish a mapping between the set name and whatever
your backend database likes to use.
defined error codes, and the suggested uses of the addinfo field.
</para>
+ <para>
+ The <function>bend_search</function> handler is also called when
+ the frontend server receives a SRW/SRU SearchRetrieveRequest.
+ For SRW/SRU, a CQL query is usually provided by the client.
+ The CQL query is available as part of <literal>Z_Query</literal>
+ structure (note that CQL is now part of Z39.50 via an external).
+ To support CQL in existing implementations that only do Type-1,
+ we refer to the CQL-to-PQF tool described
+ <link linkend="tools.cql.pqf">here</link>.
+ </para>
+ <para>
+ To maintain backwards compatibility, the frontend server
+ of yaz always assume that error codes are BIB-1 diagnostics.
+ For SRW/SRU operation, a Bib-1 diagnostic code is mapped to
+ SRW/SRU diagnostic.
+ </para>
+
<synopsis>
int (*bend_fetch) (void *handle, bend_fetch_rr *rr);
int errcode; /* 0==success */
char *errstring; /* system error string or NULL */
int surrogate_flag; /* surrogate diagnostic */
+ char *schema; /* string record schema input/output */
} bend_fetch_rr;
</synopsis>
<para>
The frontend server calls the <function>bend_fetch</function> handler
- when it needs database records to fulfill a Search Request or a Present
- Request.
+ when it needs database records to fulfill a Z39.50 Search Request, a
+ Z39.50 Present Request or a SRW SearchRetrieveRequest.
The <literal>setname</literal> is simply the name of the result set
that holds the reference to the desired record.
The <literal>number</literal> is the offset into the set (with 1
</para>
<para>
+ If a SRW/SRU SearchRetrieveRequest is received by the frontend server,
+ the <literal>referenceId</literal> is NULL and the
+ <literal>request_format</literal> (transfer syntax) is XML (OID name
+ <literal>VAL_TEXT_XML</literal>).
+ The schema for SRW/SRU is stored in both the
+ <literal>Z_RecordComposition</literal>
+ structure and <literal>schema</literal> (simple string).
+ </para>
+
+ <para>
In the structure, the <literal>basename</literal> is the name of the
database that holds the
record. <literal>len</literal> is the length of the record returned, in
bytes, and <literal>record</literal> is a pointer to the record.
- <literal>Last_in_set</literal> should be nonzero only if the record
+ <literal>last_in_set</literal> should be nonzero only if the record
returned is the last one in the given result set.
<literal>errcode</literal> and <literal>errstring</literal>, if
given, will be interpreted as a global error pertaining to the
<para>
The <function>bend_present</function> handler is called when
- the server receives a Present Request. The <literal>setname</literal>,
+ the server receives a Z39.50 Present Request.
+ The <literal>setname</literal>,
<literal>start</literal> and <literal>number</literal> is the
name of the result set - start position - and number of records to
be retrieved respectively. <literal>format</literal> and
} bend_scan_status;
typedef struct bend_scan_rr {
- int num_bases; /* number of elements in databaselist */
+ int num_bases; /* number of elements in database list */
char **basenames; /* databases to search */
oid_value attributeset;
Z_ReferenceId *referenceId; /* reference ID */
The finished application has the following
invocation syntax (by way of <function>statserv_main()</function>):
</para>
-
- <synopsis>
- <replaceable>appname</replaceable> [-szSiTu -a <replaceable>apdufile</replaceable> -l <replaceable>logfile</replaceable> -v <replaceable>loglevel</replaceable> -c <replaceable>config</replaceable>]
- [listener ...]
- </synopsis>
-
+
+ <cmdsynopsis>
+ <command>appname</command>
+ <arg choice="opt"><option>-a <replaceable>file</replaceable></option></arg>
+ <arg choice="opt"><option>-v <replaceable>level</replaceable></option></arg>
+ <arg choice="opt"><option>-l <replaceable>file</replaceable></option></arg>
+ <arg choice="opt"><option>-u <replaceable>uid</replaceable></option></arg>
+ <arg choice="opt"><option>-c <replaceable>config</replaceable></option></arg>
+ <arg choice="opt"><option>-t <replaceable>minutes</replaceable></option></arg>
+ <sbr/>
+ <arg choice="opt"><option>-k <replaceable>kilobytes</replaceable></option></arg>
+ <arg choice="opt"><option>-d <replaceable>daemon</replaceable></option></arg>
+ <arg choice="opt"><option>-w <replaceable>dir</replaceable></option></arg>
+ <arg choice="opt"><option>-ziST1</option></arg>
+ <arg choice="opt" rep="repeat">listener-spec</arg>
+ </cmdsynopsis>
+
<para>
- The options are
+ The options are:
- <variablelist>
-
- <varlistentry><term>-a <replaceable>file</replaceable></term>
- <listitem><para>
- Specify a file for dumping PDUs (for diagnostic purposes).
- The special name "-" sends output to
- <literal>stderr</literal>.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-S</term>
- <listitem><para>
- Don't fork or make threads on connection requests. This is good for
- debugging, but not recommended for real operation: Although the
- server is asynchronous and non-blocking, it can be nice to keep
- a software malfunction (okay then, a crash) from affecting all
- current users.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-T</term>
- <listitem><para>
- Operate the server in threaded mode. The server creates a thread
- for each connection rather than a fork a process. Only available
- on UNIX systems that offers POSIX threads.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-s</term>
- <listitem><para>
- Use the SR protocol (obsolete).
- </para></listitem></varlistentry>
-
- <varlistentry><term>-z</term>
- <listitem><para>
- Use the Z39.50 protocol (default). These two options complement
- each other. You can use both multiple times on the same command
- line, between listener-specifications (see below). This way, you
- can set up the server to listen for connections in both protocols
- concurrently, on different local ports.
- </para></listitem></varlistentry>
+ &ztest-options;
- <varlistentry><term>-l <replaceable>file</replaceable></term>
- <listitem><para>The logfile.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-c <replaceable>config</replaceable></term>
- <listitem><para>A user option that serves as a specifier for some
- sort of configuration, e.g. a filename.
- The argument to this option is transferred to member
- <literal>configname</literal>of the
- <literal>statserv_options_block</literal>.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-v <replaceable>level</replaceable></term>
- <listitem><para>
- The log level. Use a comma-separated list of members of the set
- {fatal,debug,warn,log,all,none}.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-u <replaceable>userid</replaceable></term>
- <listitem><para>
- Set user ID. Sets the real UID of the server process to that of the
- given user. It's useful if you aren't comfortable with having the
- server run as root, but you need to start it as such to bind a
- privileged port.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-w <replaceable>dir</replaceable></term>
- <listitem><para>
- Working directory.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-i</term>
- <listitem><para>
- Use this when running from the <application>inetd</application> server.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-t <replaceable>minutes</replaceable></term>
- <listitem><para>
- Idle session timeout, in minutes.
- </para></listitem></varlistentry>
-
- <varlistentry><term>-k <replaceable>size</replaceable></term>
- <listitem><para>
- Maximum record size/message size, in kilobytes.
- </para></listitem></varlistentry>
-
- </variablelist>
</para>
-
+
<para>
A listener specification consists of a transport mode followed by a
colon (:) followed by a listener address. The transport mode is
- either <literal>osi</literal> or <literal>tcp</literal>.
+ either <literal>tcp</literal>, <literal>unix:</literal> or
+ <literal>ssl</literal>.
</para>
-
+
<para>
- For TCP, an address has the form
+ For TCP and SSL, an address has the form
</para>
<synopsis>
</para>
<para>
- For osi, the address form is
+ For UNIX, the address is the filename of socket.
</para>
- <synopsis>
- [t-selector /] hostname | IP-number [: portnumber]
- </synopsis>
-
<para>
- The transport selector is given as a string of hex digits (with an even
- number of digits). The default port number is 102 (RFC1006 port).
+ For TCP/IP and SSL, the special hostname "@" is mapped to
+ the address <literal>INADDR_ANY</literal>, which causes the
+ server to listen on any local interface.
</para>
-
+
<para>
- Examples
- </para>
-
+ Examples:
<screen>
- tcp:dranet.dra.com
+ tcp:@:210
- osi:0402/dbserver.osiworld.com:3000
- </screen>
-
- <para>
- In both cases, the special hostname "@" is mapped to
- the address INADDR_ANY, which causes the server to listen on any local
- interface. To start the server listening on the registered ports for
- Z39.50 and SR over OSI/RFC1006, and to drop root privileges once the
- ports are bound, execute the server like this (from a root shell):
- </para>
+ ssl:@:3000
- <screen>
- my-server -u daemon tcp:@ -s osi:@
+ unix:/tmp/yaz
</screen>
-
- <para>
- You can replace <literal>daemon</literal> with another user, eg. your
- own account, or a dedicated IR server account.
- <literal>my-server</literal> should be the name of your
- server application. You can test the procedure with the
- <application>yaz-ztest</application> application.
</para>
</sect1>
</chapter>
-
+
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document: "yaz.xml"
- sgml-local-catalogs: "../../docbook/docbook.cat"
+ sgml-local-catalogs: nil
sgml-namecase-general:t
End:
-->