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