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