Extend presentResponse logging with proper status
[metaproxy-moved-to-github.git] / src / gduutil.cpp
1 /* This file is part of Metaproxy.
2    Copyright (C) 2005-2010 Index Data
3
4 Metaproxy is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #include "gduutil.hpp"
20 #include <metaproxy/util.hpp>
21
22 #include <yaz/wrbuf.h>
23 #include <yaz/oid_db.h>
24 #include <yaz/querytowrbuf.h>
25
26 #include <iostream>
27 #include <list>
28
29 namespace mp = metaproxy_1;
30
31 // Doxygen doesn't like mp::gdu, so we use this instead
32 namespace mp_util = metaproxy_1::util;
33
34
35
36
37 std::ostream& std::operator<<(std::ostream& os,  Z_GDU& zgdu)
38 {
39     if (zgdu.which == Z_GDU_Z3950)
40     {
41         os << "Z3950";
42         if (zgdu.u.z3950)
43             os << *(zgdu.u.z3950);
44     }
45     else if (zgdu.which == Z_GDU_HTTP_Request)
46     {
47         os << "HTTP_Request";
48         if (zgdu.u.HTTP_Request)
49             os << " " << *(zgdu.u.HTTP_Request);
50     }
51     else if (zgdu.which == Z_GDU_HTTP_Response)
52     {
53         os << "HTTP_Response";
54         if (zgdu.u.HTTP_Response)
55             os << " " << *(zgdu.u.HTTP_Response);
56     }
57     else
58         os << "Z_GDU";
59     return os;
60 }
61
62 std::ostream& std::operator<<(std::ostream& os, Z_HTTP_Request& httpreq)
63 {
64     os << httpreq.method << " ";
65     os << httpreq.path;    
66     return os;
67 }
68
69
70 std::ostream& std::operator<<(std::ostream& os, Z_HTTP_Response& httpres)
71 {
72     os << httpres.code << " ";
73     os << httpres.content_len;   
74     return os;
75 }
76
77 std::ostream& std::operator<<(std::ostream& os, Z_Records & rs)
78 {
79     switch(rs.which) {
80     case Z_Records_DBOSD :
81         break;
82     case Z_Records_NSD:
83         if (rs.u.nonSurrogateDiagnostic)
84             os << *(rs.u.nonSurrogateDiagnostic);
85         break;
86     case Z_Records_multipleNSD:
87         os << "Z_Records_multipleNSD";
88         //os << *(rs.u.multipleNonSurDiagnostics);
89         break;
90     default:
91         os << "Z_Records" ;
92     }
93     
94     return os;
95 }
96
97 std::ostream& std::operator<<(std::ostream& os, Z_DiagRec& dr)
98 {
99     switch(dr.which) {
100     case Z_DiagRec_defaultFormat:
101         if (dr.u.defaultFormat)
102             os << *(dr.u.defaultFormat);
103         break;
104     case Z_DiagRec_externallyDefined :
105         os << "Z_DiagRec_externallyDefined";
106         break;
107     default:
108         os << "Z_DiagRec" ;
109     }
110     
111     return os;
112 }
113
114 std::ostream& std::operator<<(std::ostream& os, Z_DefaultDiagFormat& ddf)
115 {
116     if (ddf.condition)
117         os << *(ddf.condition) << " ";
118
119     switch(ddf.which) {
120     case Z_DefaultDiagFormat_v2Addinfo:
121         os << ddf.u.v2Addinfo;
122         break;
123     case Z_DefaultDiagFormat_v3Addinfo:
124         os << ddf.u.v3Addinfo;
125         break;
126     default:
127         os << "Z_DefaultDiagFormat" ;
128     }
129     
130     return os;
131 }
132
133 static void dump_opt_string(std::ostream& os, const char *s)
134 {
135     os << " ";
136     if (s)
137         os << s;
138     else
139         os << "-";
140 }
141
142 static void dump_opt_int(std::ostream& os, const Odr_int *i)
143 {
144     os << " ";
145     if (i)
146         os << *i;
147     else
148         os << "-";
149 }
150
151 std::ostream& std::operator<<(std::ostream& os,  Z_APDU& zapdu)
152 {
153     switch(zapdu.which) {
154
155     case Z_APDU_initRequest:
156         os << " " << "initRequest";
157                         
158         {
159             Z_InitRequest *ir 
160                 = zapdu.u.initRequest;
161
162             Z_IdAuthentication *a = ir->idAuthentication;
163             if (a && a->which == Z_IdAuthentication_idPass)
164                 dump_opt_string(os, a->u.idPass->userId);
165             else if (a && a->which == Z_IdAuthentication_open)
166                 dump_opt_string(os, a->u.open);
167             else
168                 dump_opt_string(os, 0);
169             
170             os << " ";
171             std::list<std::string> vhosts;
172             mp::util::get_vhost_otherinfo(ir->otherInfo, vhosts);
173             if (vhosts.size()){
174                 copy(vhosts.begin(), vhosts.end(), 
175                      ostream_iterator<string>(os, " "));
176             }
177             else
178                 os << "-" ;
179             
180             dump_opt_string(os, ir->implementationId);
181             dump_opt_string(os, ir->implementationName);
182             dump_opt_string(os, ir->implementationVersion);
183         }
184         break;
185     case Z_APDU_initResponse:
186         os << " " << "initResponse ";
187         {
188             Z_InitResponse *ir 
189                 = zapdu.u.initResponse;
190             if (ir->result && *(ir->result))
191             {
192                 os << "OK";
193             }
194             else
195             {
196                 os << "FAIL";
197             }
198             dump_opt_string(os, ir->implementationId);
199             dump_opt_string(os, ir->implementationName);
200             dump_opt_string(os, ir->implementationVersion);
201         }
202         break;
203     case Z_APDU_searchRequest:
204         os << " " << "searchRequest" << " ";
205         { 
206             Z_SearchRequest *sr 
207                 = zapdu.u.searchRequest;
208                             
209             for (int i = 0; i < sr->num_databaseNames; i++)
210             {
211                 os << sr->databaseNames[i];
212                 if (i+1 !=  sr->num_databaseNames)
213                     os << "+";
214             }
215
216             dump_opt_string(os, sr->resultSetName);
217
218             os << " ";
219             if (sr->preferredRecordSyntax)
220             {
221                 char oid_name_str[OID_STR_MAX];
222                 const char *oid_name = yaz_oid_to_string_buf(
223                     sr->preferredRecordSyntax, 0, oid_name_str);
224                 
225                 os << oid_name;
226             }
227             else
228                 os << "-";
229
230             os << " ";
231             WRBUF wr = wrbuf_alloc();
232             yaz_query_to_wrbuf(wr, sr->query);
233             os << wrbuf_cstr(wr);
234             wrbuf_destroy(wr);
235         }
236         break;
237     case Z_APDU_searchResponse:
238         os << " " << "searchResponse ";
239         {
240             Z_SearchResponse *sr 
241                 = zapdu.u.searchResponse;
242             if (sr->searchStatus && *(sr->searchStatus))
243             {
244                 os << "OK";
245                 dump_opt_int(os, sr->resultCount);
246                 dump_opt_int(os, sr->numberOfRecordsReturned);
247                 dump_opt_int(os, sr->nextResultSetPosition);
248             }
249             else 
250                 if (sr->records)
251                     os << "DIAG " << *(sr->records);
252                 else
253                     os << "ERROR";
254         }
255         break;
256     case Z_APDU_presentRequest:
257         os << " " << "presentRequest";
258         {
259             Z_PresentRequest *pr = zapdu.u.presentRequest;
260             dump_opt_string(os, pr->resultSetId);
261             dump_opt_int(os, pr->resultSetStartPoint);
262             dump_opt_int(os, pr->numberOfRecordsRequested);
263             if (pr->preferredRecordSyntax)
264             {
265                 char oid_name_str[OID_STR_MAX];
266                 const char *oid_name = yaz_oid_to_string_buf(
267                     pr->preferredRecordSyntax, 0, oid_name_str);
268                     
269                 os << " " << oid_name;
270             }
271             else
272                 os << " -";
273             const char * msg = 0;
274             if (pr->recordComposition)
275                 msg = mp_util::record_composition_to_esn(pr->recordComposition);
276             dump_opt_string(os, msg);
277         }
278         break;
279     case Z_APDU_presentResponse:
280         os << " " << "presentResponse" << " ";
281         {
282             Z_PresentResponse *pr 
283                 = zapdu.u.presentResponse;
284             if (pr->presentStatus && 
285                 *pr->presentStatus != Z_PresentStatus_failure)
286             {
287                 switch (*pr->presentStatus)
288                 {
289                 case Z_PresentStatus_success:
290                     os << "OK"; break;
291                 case Z_PresentStatus_partial_1:
292                     os << "Partial-1"; break;
293                 case Z_PresentStatus_partial_2:
294                     os << "Partial-2"; break;
295                 case Z_PresentStatus_partial_3:
296                     os << "Partial-3"; break;
297                 case Z_PresentStatus_partial_4:
298                     os << "Partial-4"; break;
299                 default:
300                     os << "Unknown"; break;
301                 }
302                 //<< pr->referenceId << " "
303                 if (pr->numberOfRecordsReturned)
304                     os << " " << *(pr->numberOfRecordsReturned);
305                 else
306                     os << " -";
307                 if (pr->nextResultSetPosition)
308                     os << " " << *(pr->nextResultSetPosition);
309                 else
310                     os << " -";
311             }
312             else
313                 if (pr->records)
314                     os << "DIAG " << *(pr->records);
315                 else
316                     os << "ERROR";
317
318             //os << "DIAG" << " "
319             //<< "-" << " "
320             //<< pr->referenceId << " "
321             //<< *(pr->numberOfRecordsReturned) << " "
322             //<< *(pr->nextResultSetPosition);
323         }
324         break;
325     case Z_APDU_deleteResultSetRequest:
326         os << " " << "deleteResultSetRequest";
327         break;
328     case Z_APDU_deleteResultSetResponse:
329         os << " " << "deleteResultSetResponse";
330         break;
331     case Z_APDU_accessControlRequest:
332         os << " " << "accessControlRequest";
333         break;
334     case Z_APDU_accessControlResponse:
335         os << " " << "accessControlResponse";
336         break;
337     case Z_APDU_resourceControlRequest:
338         os << " " << "resourceControlRequest";
339         break;
340     case Z_APDU_resourceControlResponse:
341         os << " " << "resourceControlResponse";
342         break;
343     case Z_APDU_triggerResourceControlRequest:
344         os << " " << "triggerResourceControlRequest";
345         break;
346     case Z_APDU_resourceReportRequest:
347         os << " " << "resourceReportRequest";
348         break;
349     case Z_APDU_resourceReportResponse:
350         os << " " << "resourceReportResponse";
351         break;
352     case Z_APDU_scanRequest:
353         os << " " << "scanRequest" << " ";
354         { 
355             Z_ScanRequest *sr 
356                 = zapdu.u.scanRequest;
357                         
358             if (sr)
359             {
360                 for (int i = 0; i < sr->num_databaseNames; i++)
361                 {
362                     os << sr->databaseNames[i];
363                     if (i+1 !=  sr->num_databaseNames)
364                         os << "+";
365                 }
366                 dump_opt_int(os, sr->numberOfTermsRequested);
367                 dump_opt_int(os, sr->preferredPositionInResponse);
368                 dump_opt_int(os, sr->stepSize);
369
370                 os << " ";
371                 if (sr->termListAndStartPoint)
372                 {
373                     WRBUF wr = wrbuf_alloc();
374                     yaz_scan_to_wrbuf(wr, sr->termListAndStartPoint, 
375                                       sr->attributeSet);
376                     os << wrbuf_cstr(wr);
377                     wrbuf_destroy(wr);
378                 }
379                 else
380                     os << "-";
381             }
382         }
383         break;
384     case Z_APDU_scanResponse:
385         os << " " << "scanResponse" << " ";
386         {
387             Z_ScanResponse *sr 
388                 = zapdu.u.scanResponse;
389             if (sr)
390             {
391                 if (!sr->scanStatus)
392                 {
393                     os << "OK";
394                 }
395                 else
396                 {
397                     switch (*(sr->scanStatus)){
398                     case Z_Scan_success:
399                         os << "OK";
400                         break;
401                     case Z_Scan_partial_1:
402                         os << "partial_1";
403                         break;
404                     case Z_Scan_partial_2:
405                         os << "partial_2";
406                         break;
407                     case Z_Scan_partial_3:
408                         os << "partial_3";
409                         break;
410                     case Z_Scan_partial_4:
411                         os << "partial_4";
412                         break;
413                     case Z_Scan_partial_5:
414                         os << "partial_5";
415                         break;
416                     case Z_Scan_failure:
417                         os << "failure";
418                         break;
419                     default:
420                         os << "unknown";
421                     }
422                 }
423                 dump_opt_int(os, sr->numberOfEntriesReturned);
424                 dump_opt_int(os, sr->positionOfTerm);
425                 dump_opt_int(os, sr->stepSize);
426             }
427         }
428         break;
429     case Z_APDU_sortRequest:
430         os << " " << "sortRequest" << " ";
431         break;
432     case Z_APDU_sortResponse:
433         os << " " << "sortResponse" << " ";
434         break;
435     case Z_APDU_segmentRequest:
436         os << " " << "segmentRequest" << " ";
437         break;
438     case Z_APDU_extendedServicesRequest:
439         os << " " << "extendedServicesRequest";
440         { 
441             Z_ExtendedServicesRequest *er 
442                 = zapdu.u.extendedServicesRequest;
443             if (er)
444             {
445                 if (er->function)
446                 {
447                     os << " ";
448                     switch(*(er->function))
449                     {
450                     case Z_ExtendedServicesRequest_create:
451                         os << "create";
452                         break;
453                     case Z_ExtendedServicesRequest_delete:
454                         os << "delete";
455                         break;
456                     case Z_ExtendedServicesRequest_modify:
457                         os << "modify";
458                         break;
459                     default:
460                         os << "unknown";
461                     }
462                 }
463                 else
464                     os << " -";
465                     
466                 
467                 if (er->userId)
468                     os << " " << er->userId ;
469                 else
470                     os << " -";
471                 
472                 if (er->packageName)
473                     os << " " << er->packageName;
474                 else
475                     os << " -";
476                 
477                 if (er->description)
478                     os << " " << er->description;
479                 else
480                     os << " -";
481             }
482         }
483         break;
484     case Z_APDU_extendedServicesResponse:
485         os << " " << "extendedServicesResponse";
486          { 
487              Z_ExtendedServicesResponse *er 
488                  = zapdu.u.extendedServicesResponse;
489              if (er)
490              {
491                  if (er->operationStatus)
492                  {
493                      os << " ";
494                      switch (*(er->operationStatus)){
495                      case Z_ExtendedServicesResponse_done:
496                          os << "OK";
497                          break;
498                      case Z_ExtendedServicesResponse_accepted:
499                          os << "ACCEPT";
500                          break;
501                      case Z_ExtendedServicesResponse_failure:
502                          if (er->num_diagnostics)
503                              os << "DIAG " << **(er->diagnostics);
504                          else
505                              os << "ERROR";
506                          break;
507                      default:
508                          os << "unknown";
509                      }
510                  }
511                  else
512                      os << " -";
513              }
514          }
515         break;
516     case Z_APDU_close:
517         os  << " " << "close" << " ";
518         { 
519             Z_Close  *c 
520                 = zapdu.u.close;
521             if (c)
522             {
523                 if (c->closeReason)
524                 {
525                     os << *(c->closeReason) << " ";
526
527                     switch (*(c->closeReason)) {
528                     case Z_Close_finished:
529                         os << "finished";
530                         break;
531                     case Z_Close_shutdown:
532                         os << "shutdown";
533                         break;
534                     case Z_Close_systemProblem:
535                         os << "systemProblem";
536                         break;
537                     case Z_Close_costLimit:
538                         os << "costLimit";
539                         break;
540                     case Z_Close_resources:
541                         os << "resources";
542                         break;
543                     case Z_Close_securityViolation:
544                         os << "securityViolation";
545                         break;
546                     case Z_Close_protocolError:
547                         os << "protocolError";
548                         break;
549                     case Z_Close_lackOfActivity:
550                         os << "lackOfActivity";
551                         break;
552                     case Z_Close_peerAbort:
553                         os << "peerAbort";
554                         break;
555                     case Z_Close_unspecified:
556                         os << "unspecified";
557                         break;
558                     default:
559                         os << "unknown";
560                     }
561                 }
562                 
563                 if (c->diagnosticInformation)
564                     os << " " << c->diagnosticInformation;
565             }
566         }
567         break;
568     case Z_APDU_duplicateDetectionRequest:
569         os << " " << "duplicateDetectionRequest";
570         break;
571     case Z_APDU_duplicateDetectionResponse:
572         os << " " << "duplicateDetectionResponse";
573         break;
574     default: 
575         os << " " << "Z_APDU " << "UNKNOWN";
576     }
577
578     return os;
579 }
580
581
582
583
584 /*
585  * Local variables:
586  * c-basic-offset: 4
587  * c-file-style: "Stroustrup"
588  * indent-tabs-mode: nil
589  * End:
590  * vim: shiftwidth=4 tabstop=8 expandtab
591  */
592