]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/srfsh/srfsh.c
added json pretty printer for formatting result content data
[Evergreen.git] / OpenSRF / src / srfsh / srfsh.c
1 #include "opensrf/transport_client.h"
2 #include "opensrf/generic_utils.h"
3 #include "opensrf/osrf_message.h"
4 #include "opensrf/osrf_app_session.h"
5 #include <time.h>
6
7 #define SRFSH_PORT 5222
8 #define COMMAND_BUFSIZE 12
9
10
11 char* prompt = "srfsh# ";
12 char* last_request;
13 transport_client* client = NULL;
14
15 int parse_request( char* request );
16 int handle_router( char* words[] );
17 int handle_time( char* words[] );
18 int handle_request( char* words[] );
19 int send_request( char* server, char* method, growing_buffer* buffer );
20 int parse_error( char* words[] );
21 int router_query_servers( char* server );
22 int srfsh_client_connect();
23 void print_help();
24 char* json_printer( json* object );
25 char* tabs(int count);
26
27 int main( int argc, char* argv[] ) {
28
29
30         if( argc < 5 ) 
31                 fatal_handler( "usage: %s <jabbersever> <username> <password> <config_file>", argv[0] );
32                 
33         config_reader_init( "opensrf", argv[4] );       
34
35         char request[256];
36         memset(request, 0, 256);
37         printf(prompt);
38
39         client = client_init( argv[1], SRFSH_PORT, 0 );
40         if( ! client_connect( client, argv[2], argv[3], "srfsh", 5, AUTH_DIGEST ) ) {
41                 fprintf(stderr, "Unable to connect to jabber server '%s' as '%s'\n", argv[1], argv[2]);
42                 fprintf(stderr, "Most queries will be futile...\n" );
43         }
44
45         if( ! osrf_system_bootstrap_client("srfsh.xml") ) 
46                 fprintf( stderr, "Unable to bootstrap client for requests\n");
47
48
49         while( fgets( request, 255, stdin) ) {
50
51                 // remove newline
52                 request[strlen(request)-1] = '\0';
53
54                 if( !strcmp(request, "exit") || !strcmp(request,"quit")) { 
55                         client_disconnect( client );
56                         client_free( client );  
57                         break; 
58                 }
59
60                 if(!strcmp(request,"last")) {
61                         if(last_request) {
62                                 memset(request,0,256);
63                                 strcpy(request, last_request);
64                                 printf("%s\n", request);
65                         } else {
66                                 printf(prompt);
67                                 continue;
68                         }
69                 }
70
71                 char* req_copy = strdup(request);
72
73                 if( !strcmp(request, "help") || !strcmp(request,"?")) 
74                         print_help();
75                 else {
76                         if(parse_request( req_copy ) && strcmp(request,"last") ) {
77                                 free(last_request);
78                                 last_request = strdup(request);
79                         }
80                 }
81
82
83                 printf(prompt);
84                 memset(request, 0, 300);
85                 free(req_copy);
86         }
87
88         fprintf(stderr, "Exiting...\n[Ignore Segfault]\n");
89
90         config_reader_free();   
91         log_free();
92
93         return 0;
94 }
95
96
97 int parse_error( char* words[] ) {
98
99         if( ! words )
100                 return 0;
101
102         int i = 0;
103         char* current;
104         char buffer[256];
105         memset(buffer, 0, 256);
106         while( (current=words[i++]) ) {
107                 strcat(buffer, current);
108                 strcat(buffer, " ");
109         }
110         if( ! buffer || strlen(buffer) < 1 ) 
111                 printf("\n");
112
113         fprintf( stderr, "Command Incomplete or Not Recognized: %s\n", buffer );
114         return 0;
115
116 }
117
118
119 int parse_request( char* request ) {
120
121         if( request == NULL )
122                 return 0;
123
124         int ret_val = 0;
125         int i = 0;
126         char* words[COMMAND_BUFSIZE]; 
127         memset(words,0,COMMAND_BUFSIZE);
128         //char* req = strdup(request);
129         char* req = request;
130
131         char* cur_tok = strtok( req, " " );
132
133         if( cur_tok == NULL )
134                 return 0;
135
136         while(cur_tok != NULL) {
137                 words[i++] = cur_tok;
138                 cur_tok = strtok( NULL, " " );
139         }
140
141         //free(req);
142
143         // not sure why (strtok?), but this is necessary
144         memset( words + i, 0, COMMAND_BUFSIZE - i );
145
146         /* pass off to the top level command */
147         if( !strcmp(words[0],"router") ) 
148                 ret_val = handle_router( words );
149
150         else if( !strcmp(words[0],"time") ) 
151                 ret_val = handle_time( words );
152
153         else if (!strcmp(words[0],"request"))
154                 ret_val = handle_request( words );
155
156         if(!ret_val)
157                 return parse_error( words );
158
159         return 1;
160
161 }
162
163
164 int handle_router( char* words[] ) {
165
166         if(!client)
167                 return 1;
168
169         int i;
170
171         if( words[1] ) { 
172                 if( !strcmp(words[1],"query") ) {
173                         
174                         if( words[2] && !strcmp(words[2],"servers") ) {
175                                 for(i=3; i < COMMAND_BUFSIZE - 3 && words[i]; i++ ) {   
176                                         router_query_servers( words[i] );
177                                 }
178                                 return 1;
179                         }
180                         return 0;
181                 }
182                 return 0;
183         }
184         return 0;
185 }
186
187 int handle_request( char* words[] ) {
188
189         if(!client)
190                 return 1;
191
192         if(words[1]) {
193                 char* server = words[1];
194                 char* method = words[2];
195                 int i;
196                 growing_buffer* buffer = buffer_init(128);
197
198                 buffer_add(buffer, "[");
199                 for(i = 3; words[i] != NULL; i++ ) {
200                         buffer_add( buffer, words[i] );
201                         buffer_add(buffer, " ");
202                 }
203                 buffer_add(buffer, "]");
204
205                 return send_request( server, method, buffer );
206         } 
207
208         return 0;
209 }
210
211 int send_request( char* server, char* method, growing_buffer* buffer ) {
212         if( server == NULL || method == NULL )
213                 return 0;
214
215         json* params = NULL;
216         if( buffer != NULL && buffer->n_used > 0 ) 
217                 params = json_tokener_parse(buffer->buf);
218
219         osrf_app_session* session = osrf_app_client_session_init(server);
220         double start = get_timestamp_millis();
221
222         if(!osrf_app_session_connect(session)) {
223                 warning_handler( "Unable to connect to remote service %s\n", server );
224                 return 1;
225         }
226
227         int req_id = osrf_app_session_make_request( session, params, method, 1 );
228
229         osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 8 );
230
231         if(!omsg) 
232                 printf("Received no data from server\n");
233         
234         
235         while(omsg) {
236                 if(omsg->result_content) {
237                         char* content = json_printer( omsg->result_content );
238                         printf( "Received Data: %s\n",content );
239                         free(content);
240                 }
241                 else
242                         printf( "Received Message but no result data\n");
243
244                 osrf_message_free(omsg);
245                 omsg = osrf_app_session_request_recv( session, req_id, 5 );
246         }
247
248
249         if( osrf_app_session_request_complete( session, req_id ))
250                 printf("[Request Completed Successfully]\n");
251
252         double end = get_timestamp_millis();
253
254         printf("Request Time in seconds: %f\n", end - start );
255
256         osrf_app_session_disconnect( session );
257
258         return 1;
259
260
261 }
262
263 int handle_time( char* words[] ) {
264
265         if( ! words[1] ) {
266
267                 char buf[36];
268                 memset(buf,0,36);
269                 get_timestamp(buf);
270                 printf( "%s\n", buf );
271                 return 1;
272         }
273
274         if( words[1] ) {
275                 time_t epoch = (time_t)atoi( words[1] );
276                 char* localtime = strdup( ctime( &epoch ) );
277                 printf( "%s => %s", words[1], localtime );
278                 free(localtime);
279                 return 1;
280         }
281
282         return 0;
283
284 }
285
286                 
287
288 int router_query_servers( char* router_server ) {
289
290         if( ! router_server || strlen(router_server) == 0 ) 
291                 return 0;
292
293         char rbuf[256];
294         memset(rbuf,0,256);
295         sprintf(rbuf,"router@%s/router", router_server );
296                 
297         transport_message* send = 
298                 message_init( "servers", NULL, NULL, rbuf, NULL );
299         message_set_router_info( send, NULL, NULL, NULL, "query", 0 );
300
301         client_send_message( client, send );
302         message_free( send );
303
304         transport_message* recv = client_recv( client, -1 );
305         if( recv == NULL )
306                 fprintf(stderr, "NULL message received from router\n");
307         
308         printf( 
309                         "---------------------------------------------------------------------------------\n"
310                         "Received from 'server' query on %s\n"
311                         "---------------------------------------------------------------------------------\n"
312                         "original reg time | latest reg time | last used time | class | server\n"
313                         "---------------------------------------------------------------------------------\n"
314                         "%s"
315                         "---------------------------------------------------------------------------------\n"
316                         , router_server, recv->body );
317
318         message_free( recv );
319         
320         return 1;
321 }
322                 
323 void print_help() {
324
325         printf(
326                         "---------------------------------------------------------------------------------\n"
327                         "Commands:\n"
328                         "---------------------------------------------------------------------------------\n"
329                         "help                   - Display this message\n"
330                         "last                   - Re-performs the last command\n"
331                         "time                   - Prints the current time\n"                                    
332                         "time <timestamp>       - Formats seconds since epoch into readable format\n"   
333                         "---------------------------------------------------------------------------------\n"
334                         "router query servers <server1 [, server2, ...]>\n"
335                         "       - Returns stats on connected services\n"
336                         "reqeust <service> <method> [ <json formatted string of params> ]\n"
337                         "       - Anything passed in will be wrapped in a json array\n"
338                         "---------------------------------------------------------------------------------\n"
339                         );
340
341 }
342
343
344
345 char* tabs(int count) {
346         growing_buffer* buf = buffer_init(24);
347         int i;
348         for(i=0;i!=count;i++)
349                 buffer_add(buf, "   ");
350
351         char* final = buffer_data( buf );
352         buffer_free( buf );
353         return final;
354 }
355
356 char* json_printer( json* object ) {
357
358         if(object == NULL)
359                 return NULL;
360         char* string = json_object_to_json_string(object);
361
362         growing_buffer* buf = buffer_init(64);
363         int i;
364         int tab_var = 0;
365         for(i=0; i!= strlen(string); i++) {
366
367                 if( string[i] == '{' ) {
368
369                         buffer_add(buf, "\n");
370                         char* tab = tabs(tab_var);
371                         buffer_add(buf, tab);
372                         free(tab);
373                         buffer_add( buf, "{");
374                         tab_var++;
375                         buffer_add( buf, "\n" );        
376                         tab = tabs(tab_var);
377                         buffer_add( buf, tab ); 
378                         free(tab);
379
380                 } else if( string[i] == '[' ) {
381
382                         buffer_add(buf, "\n");
383                         char* tab = tabs(tab_var);
384                         buffer_add(buf, tab);
385                         free(tab);
386                         buffer_add( buf, "[");
387                         tab_var++;
388                         buffer_add( buf, "\n" );        
389                         tab = tabs(tab_var);
390                         buffer_add( buf, tab ); 
391                         free(tab);
392
393                 } else if( string[i] == '}' ) {
394
395                         tab_var--;
396                         buffer_add(buf, "\n");
397                         char* tab = tabs(tab_var);
398                         buffer_add(buf, tab);
399                         free(tab);
400                         buffer_add( buf, "}");
401                         buffer_add( buf, "\n" );        
402                         tab = tabs(tab_var);
403                         buffer_add( buf, tab ); 
404                         free(tab);
405
406                 } else if( string[i] == ']' ) {
407
408                         tab_var--;
409                         buffer_add(buf, "\n");
410                         char* tab = tabs(tab_var);
411                         buffer_add(buf, tab);
412                         free(tab);
413                         buffer_add( buf, "]");
414                         buffer_add( buf, "\n" );        
415                         tab = tabs(tab_var);
416                         buffer_add( buf, tab ); 
417                         free(tab);
418
419                 } else {
420                         char b[2];
421                         b[0] = string[i];
422                         b[1] = '\0';
423                         buffer_add( buf, b ); 
424                 }
425
426         }
427
428         char* result = buffer_data(buf);
429         buffer_free(buf);
430         return result;
431
432 }