Introducing namespace yazpp_1 for all YAZ++ functions. This will
[yazpp-moved-to-github.git] / src / yaz-my-server.cpp
1 /*
2  * Copyright (c) 1998-2001, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-my-server.cpp,v 1.17 2005-06-02 06:40:21 adam Exp $
6  */
7
8 #include <stdlib.h>
9 #include <yaz/log.h>
10 #include <yaz/diagbib1.h>
11 #include <yaz/options.h>
12 #include <yaz++/z-server.h>
13 #include <yaz++/pdu-assoc.h>
14 #include <yaz++/socket-manager.h>
15
16 using namespace yazpp_1;
17
18 class MyILL : public Yaz_Facility_ILL {
19 public:
20     void ill_service (Z_ExtendedServicesRequest *req,
21                       Z_ItemOrder *io,
22                       Z_ExtendedServicesResponse *res);
23 };
24
25 class MyUpdate : public Yaz_Facility_Update {
26 public:
27     void update_service (Z_ExtendedServicesRequest *req,
28                          Z_IUUpdate *io,
29                          Z_ExtendedServicesResponse *res);
30     void update_service0 (Z_ExtendedServicesRequest *req,
31                          Z_IU0Update *io,
32                          Z_ExtendedServicesResponse *res);
33 };
34
35
36 class MyRetrieval : public Yaz_Facility_Retrieval, Yaz_USMARC {
37 public:
38     int sr_init (Z_InitRequest *initRequest,
39                  Z_InitResponse *initResponse);
40     void sr_search (Z_SearchRequest *searchRequest,
41                         Z_SearchResponse *searchResponse);
42     void sr_present (Z_PresentRequest *presentRequest,
43                          Z_PresentResponse *presentResponse);
44     void sr_record (const char *resultSetName,
45                     int position,
46                     int *format,
47                     Z_RecordComposition *comp,
48                     Z_NamePlusRecord *namePlusRecord,
49                     Z_Records *records);
50 };
51
52 class MyServer : public Yaz_Z_Server {
53 public:
54     ~MyServer();
55     MyServer(IYaz_PDU_Observable *the_PDU_Observable);
56     IYaz_PDU_Observer* sessionNotify(IYaz_PDU_Observable *the_PDU_Observable,
57                                      int fd);
58     void failNotify();
59     void timeoutNotify();
60     void connectNotify();
61
62 private:
63     MyRetrieval m_retrieval;
64     MyILL       m_ill;
65     MyUpdate    m_update;
66     int m_no;
67 };
68
69 void MyILL::ill_service (Z_ExtendedServicesRequest *req,
70                          Z_ItemOrder *io,
71                          Z_ExtendedServicesResponse *res)
72 {
73     yaz_log (YLOG_LOG, "MyServer::ill_service");
74 }
75
76 void MyUpdate::update_service (Z_ExtendedServicesRequest *req,
77                            Z_IUUpdate *io,
78                            Z_ExtendedServicesResponse *res)
79 {
80     yaz_log (YLOG_LOG, "MyServer::update_service (v1.1)");
81 }
82
83 void MyUpdate::update_service0 (Z_ExtendedServicesRequest *req,
84                            Z_IU0Update *io,
85                                 Z_ExtendedServicesResponse *res)
86 {
87     yaz_log (YLOG_LOG, "MyServer::update_service (v1.0)");
88 }
89
90 int MyRetrieval::sr_init (Z_InitRequest *initRequest,
91                        Z_InitResponse *initResponse)
92 {
93     yaz_log (YLOG_LOG, "MyServer::sr_init");
94     return 1;
95 }
96
97 void MyRetrieval::sr_search (Z_SearchRequest *searchRequest,
98                              Z_SearchResponse *searchResponse)
99 {
100     yaz_log (YLOG_LOG, "MyServer::recv_Z_search");
101     if (searchRequest->query->which == Z_Query_type_1)
102     {
103         Z_RPNStructure *s = searchRequest->query->u.type_1->RPNStructure;
104         if (s->which == Z_RPNStructure_simple &&
105             s->u.simple->which == Z_Operand_APT &&
106             s->u.simple->u.attributesPlusTerm->term->which == Z_Term_general)
107         {
108             Odr_oct *term = s->u.simple->u.attributesPlusTerm->term->u.general;
109             char *str = (char *) odr_malloc (odr_encode(), term->len+1);
110             if (term->len)
111                 memcpy (str, term->buf, term->len);
112             str[term->len] = '\0';
113             *searchResponse->resultCount = atoi(str);
114         }
115     }
116 }
117
118 void MyRetrieval::sr_present (Z_PresentRequest *presentRequest,
119                                Z_PresentResponse *presentResponse)
120 {
121     yaz_log (YLOG_LOG, "MyServer::recv_Z_present");
122 }
123
124 void MyRetrieval::sr_record (const char *resultSetName,
125                              int position,
126                              int *format,
127                              Z_RecordComposition *comp,
128                              Z_NamePlusRecord *namePlusRecord,
129                              Z_Records *records)
130 {
131     yaz_log (YLOG_LOG, "MyServer::recv_Z_record");
132     const char *rec = get_record(position);
133     if (rec)
134         create_databaseRecord (odr_encode(), namePlusRecord, 0,
135                                VAL_USMARC, rec, strlen(rec));
136     else
137         create_surrogateDiagnostics(odr_encode(), namePlusRecord, 0,
138                                     YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, 0);
139 }
140
141 MyServer::~MyServer()
142 {
143 }
144
145 IYaz_PDU_Observer *MyServer::sessionNotify(
146     IYaz_PDU_Observable *the_PDU_Observable, int fd)
147 {
148     MyServer *new_server;
149     m_no++;
150     new_server = new MyServer(the_PDU_Observable);
151     new_server->timeout(900);
152     new_server->facility_add(&new_server->m_retrieval, "my sr");
153     new_server->facility_add(&new_server->m_ill, "my ill");
154     new_server->facility_add(&new_server->m_update, "my update");
155     new_server->set_APDU_log(get_APDU_log());
156
157     return new_server;
158 }
159
160 MyServer::MyServer(IYaz_PDU_Observable *the_PDU_Observable) :
161     Yaz_Z_Server (the_PDU_Observable)
162 {
163     m_no = 0;
164 }
165
166 void MyServer::timeoutNotify()
167 {
168     yaz_log (YLOG_LOG, "connection timed out");
169     delete this;
170 }
171
172 void MyServer::failNotify()
173 {
174     yaz_log (YLOG_LOG, "connection closed by client");
175     delete this;
176 }
177
178 void MyServer::connectNotify()
179 {
180 }
181
182 void usage(const char *prog)
183 {
184     fprintf (stderr, "%s: [-a log] [-v level] [-T] @:port\n", prog);
185     exit (1);
186 }
187
188 int main(int argc, char **argv)
189 {
190     int thread_flag = 0;
191     char *arg;
192     char *prog = *argv;
193     const char *addr = "tcp:@:9999";
194     char *apdu_log = 0;
195     
196     Yaz_SocketManager mySocketManager;
197     
198     Yaz_PDU_Assoc *my_PDU_Assoc = 0;
199     
200     MyServer *z = 0;
201     int ret;
202     
203     while ((ret = options("a:v:T", argv, argc, &arg)) != -2)
204     {
205         switch (ret)
206         {
207         case 0:
208             addr = xstrdup(arg);
209             break;
210         case 'a':
211             apdu_log = xstrdup(arg);
212             break;
213         case 'v':
214             yaz_log_init_level (yaz_log_mask_str(arg));
215             break;
216         case 'T':
217             thread_flag = 1;
218             break;
219         default:
220             usage(prog);
221             return 1;
222         }
223     }
224 #if YAZ_POSIX_THREADS
225     if (thread_flag)
226         my_PDU_Assoc = new Yaz_PDU_AssocThread(&mySocketManager);
227     else
228         my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager);
229 #else
230     my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager);
231 #endif
232     
233     z = new MyServer(my_PDU_Assoc);
234     z->server(addr);
235     if (apdu_log)
236     {
237         yaz_log (YLOG_LOG, "set_APDU_log %s", apdu_log);
238         z->set_APDU_log(apdu_log);
239     }
240
241     while (mySocketManager.processEvent() > 0)
242         ;
243     delete z;
244     return 0;
245 }