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