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