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