]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/libstack/osrf_stack.c
added CONNECT handling
[working/Evergreen.git] / OpenSRF / src / libstack / osrf_stack.c
1 #include "osrf_stack.h"
2 #include "osrf_application.h"
3
4 osrf_message* _do_client( osrf_app_session*, osrf_message* );
5 osrf_message* _do_server( osrf_app_session*, osrf_message* );
6
7 /* tell osrf_app_session where the stack entry is */
8 int (*osrf_stack_entry_point) (transport_client*, int)  = &osrf_stack_process;
9
10 int osrf_stack_process( transport_client* client, int timeout ) {
11         if( !client ) return -1;
12         transport_message* msg = NULL;
13
14         while( (msg = client_recv( client, timeout )) ) {
15                 debug_handler( "Received message from transport code from %s", msg->sender );
16                 osrf_stack_transport_handler( msg, NULL );
17                 timeout = 0;
18         }
19
20         return 0;
21 }
22
23
24
25 // -----------------------------------------------------------------------------
26 // Entry point into the stack
27 // -----------------------------------------------------------------------------
28 osrfAppSession* osrf_stack_transport_handler( transport_message* msg, char* my_service ) { 
29
30         if(!msg) return NULL;
31
32         debug_handler( "Transport handler received new message \nfrom %s "
33                         "to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body );
34
35         if(! msg->thread  && ! msg->is_error ) {
36                 warning_handler("Received a non-error message with no thread trace... dropping");
37                 message_free( msg );
38         }
39
40         osrf_app_session* session = osrf_app_session_find_session( msg->thread );
41
42         if( !session ) 
43                 session = osrf_app_server_session_init( msg->thread, my_service, msg->sender);
44
45         if( !session ) return NULL;
46
47         if(!msg->is_error)
48                 debug_handler("Session [%s] found or built", session->session_id );
49
50         osrf_app_session_set_remote( session, msg->sender );
51         osrf_message* arr[OSRF_MAX_MSGS_PER_PACKET];
52         memset(arr, 0, OSRF_MAX_MSGS_PER_PACKET );
53         int num_msgs = osrf_message_deserialize(msg->body, arr, OSRF_MAX_MSGS_PER_PACKET);
54
55         debug_handler( "We received %d messages from %s", num_msgs, msg->sender );
56
57         int i;
58         for( i = 0; i != num_msgs; i++ ) {
59
60                 /* if we've received a jabber layer error message (probably talking to 
61                         someone who no longer exists) and we're not talking to the original
62                         remote id for this server, consider it a redirect and pass it up */
63                 if(msg->is_error) {
64                         warning_handler( " !!! Received Jabber layer error message" ); 
65
66                         if(strcmp(session->remote_id,session->orig_remote_id)) {
67                                 warning_handler( "Treating jabber error as redirect for tt [%d] "
68                                         "and session [%s]", arr[i]->thread_trace, session->session_id );
69
70                                 arr[i]->m_type = STATUS;
71                                 arr[i]->status_code = OSRF_STATUS_REDIRECTED;
72
73                         } else {
74                                 warning_handler(" * Jabber Error is for top level remote id [%s], no one "
75                                                 "to send my message too!!!", session->remote_id );
76                         }
77                 }
78
79                 osrf_stack_message_handler( session, arr[i] );
80         }
81
82         message_free( msg );
83         debug_handler("after msg delete");
84
85         return session;
86 }
87
88 int osrf_stack_message_handler( osrf_app_session* session, osrf_message* msg ) {
89         if(session == NULL || msg == NULL)
90                 return 0;
91
92         osrf_message* ret_msg = NULL;
93
94         if( session->type ==  OSRF_SESSION_CLIENT )
95                  ret_msg = _do_client( session, msg );
96         else
97                 ret_msg= _do_server( session, msg );
98
99         if(ret_msg) {
100                 debug_handler("passing message %d / session %s to app handler", 
101                                 msg->thread_trace, session->session_id );
102                 osrf_stack_application_handler( session, ret_msg );
103         } else
104                 osrf_message_free(msg);
105
106         return 1;
107
108
109
110 /** If we return a message, that message should be passed up the stack, 
111   * if we return NULL, we're finished for now...
112   */
113 osrf_message* _do_client( osrf_app_session* session, osrf_message* msg ) {
114         if(session == NULL || msg == NULL)
115                 return NULL;
116
117         osrf_message* new_msg;
118
119         if( msg->m_type == STATUS ) {
120                 
121                 switch( msg->status_code ) {
122
123                         case OSRF_STATUS_OK:
124                                 debug_handler("We connected successfully");
125                                 session->state = OSRF_SESSION_CONNECTED;
126                                 debug_handler( "State: %x => %s => %d", session, session->session_id, session->state );
127                                 return NULL;
128
129                         case OSRF_STATUS_COMPLETE:
130                                 osrf_app_session_set_complete( session, msg->thread_trace );
131                                 return NULL;
132
133                         case OSRF_STATUS_CONTINUE:
134                                 osrf_app_session_request_reset_timeout( session, msg->thread_trace );
135                                 return NULL;
136
137                         case OSRF_STATUS_REDIRECTED:
138                                 osrf_app_session_reset_remote( session );
139                                 session->state = OSRF_SESSION_DISCONNECTED;
140                                 osrf_app_session_request_resend( session, msg->thread_trace );
141                                 return NULL;
142
143                         case OSRF_STATUS_EXPFAILED: 
144                                 osrf_app_session_reset_remote( session );
145                                 session->state = OSRF_SESSION_DISCONNECTED;
146                                 /* set the session to 'stateful' then resend */
147                         //      osrf_app_session_request_resend( session, msg->thread_trace );
148                                 return NULL;
149
150                         case OSRF_STATUS_TIMEOUT:
151                                 osrf_app_session_reset_remote( session );
152                                 session->state = OSRF_SESSION_DISCONNECTED;
153                                 osrf_app_session_request_resend( session, msg->thread_trace );
154                                 return NULL;
155
156
157                         default:
158                                 new_msg = osrf_message_init( RESULT, msg->thread_trace, msg->protocol );
159                                 osrf_message_set_status_info( new_msg, 
160                                                 msg->status_name, msg->status_text, msg->status_code );
161                                 warning_handler("The stack doesn't know what to do with " 
162                                                 "the provided message code: %d, name %s. Passing UP.", 
163                                                 msg->status_code, msg->status_name );
164                                 new_msg->is_exception = 1;
165                                 osrf_app_session_set_complete( session, msg->thread_trace );
166                                 osrf_message_free(msg);
167                                 return new_msg;
168                 }
169
170                 return NULL;
171
172         } else if( msg->m_type == RESULT ) 
173                 return msg;
174
175         return NULL;
176
177 }
178
179
180 /** If we return a message, that message should be passed up the stack, 
181   * if we return NULL, we're finished for now...
182   */
183 osrf_message* _do_server( osrf_app_session* session, osrf_message* msg ) {
184
185         if(session == NULL || msg == NULL) return NULL;
186
187         debug_handler("Server received message of type %d", msg->m_type );
188
189         switch( msg->m_type ) {
190
191                 case STATUS:
192                                 return NULL;
193
194                 case DISCONNECT:
195                                 osrf_app_session_destroy(session);      
196                                 return NULL;
197
198                 case CONNECT:
199                                 osrfAppSessionStatus( session, 
200                                                 OSRF_STATUS_OK, msg->thread_trace, "Connection Successful" );
201                                 return NULL;
202
203                 case REQUEST:
204
205                                 debug_handler("server passing message %d to application handler "
206                                                 "for session %s", msg->thread_trace, session->session_id );
207                                 return msg;
208
209                 default:
210                         warning_handler("Server cannot handle message of type %d", msg->m_type );
211                         return NULL;
212
213         }
214 }
215
216
217
218
219 int osrf_stack_application_handler( osrf_app_session* session, osrf_message* msg ) {
220
221         if(session == NULL || msg == NULL) return 0;
222
223         if(msg->m_type == RESULT && session->type == OSRF_SESSION_CLIENT) {
224                 osrf_app_session_push_queue( session, msg ); 
225                 return 1;
226         }
227
228         if(msg->m_type != REQUEST) return 1;
229
230         char* method = msg->method_name;
231         char* app       = session->remote_service;
232         jsonObject* params = msg->_params;
233
234         osrfAppRunMethod( app, method,  session, msg->thread_trace, params );
235                 
236         return 1;
237
238 }
239