]> git.evergreen-ils.org Git - OpenSRF.git/blob - doc/OpenSRF-Messaging-Protocol.html
Patch from Scott McKellar to provide defined behavior when passing NULL to an sprintf
[OpenSRF.git] / doc / OpenSRF-Messaging-Protocol.html
1 <html>
2
3         <head>
4
5                 <title> OILS Messaging </title>
6
7         </head>
8
9         <body>
10
11
12                 <h1> Abstract </h1>
13
14                 <p>
15
16                 The OpenSRF messaging system works on two different primary layers: the transport layer and the
17                 application layer.  The transport layer manages virtual connections between client and server,
18                 while the application layer manages user/application level messages.  
19
20                 All messages must declare which protocol version they are requesting.  The current protocol level
21                 is 1.
22
23                 <h1> Transport Layer </h1>
24
25                 <p>
26                 There are currently three types of messages in the transport layer: <b>CONNECT, STATUS, </b> and
27                 <b>DISCONNECT</b>.    
28                 
29                 <p>
30                 <b>STATUS</b> messages provide general information to the transport layer and are used in different 
31                 ways throughout the system.  They are sent primarily by the server in response to client requests.  
32                 Each message comes with 
33                 a status and statusCode.  The actual status part of the STATUS message is just a helpful message 
34                 (mostly for debugging).  The 
35                 statusCode is an integer representing the exact status this message represents.  The status codes
36                 are modeled after HTTP status codes.  Currently used codes consist of the following:
37
38                 <b> <pre style="border: solid thin blue; margin: 2% 10% 2% 10%; padding-left: 50px">
39                 100     STATUS_CONTINUE
40                 200     STATUS_OK       
41                 205     STATUS_COMPLETE
42                 307     STATUS_REDIRECTED
43                 400     STATUS_BADREQUEST
44                 404     STATUS_NOTFOUND
45                 408     STATUS_TIMEOUT
46                 417     STATUS_EXPFAILED
47                 </pre> </b>
48
49                 <p>
50                 This list is likely to change at least a little.
51
52
53                 <p>
54                 The <b>CONNECT</b> message initiates the virtual connection for a client and expects a <b>STATUS</b>
55                 in return.  If the connection is successful, the statusCode for the <b>STATUS</b> message shall be
56                 <b>STATUS_OK</b>.  
57
58                 <p>
59                 If at any point the client sends a non-connect message to the server when the client is not connected or the 
60                 connection has timed out, the <b>STATUS</b> that is returned shall have statusCode <b>STATUS_EXPFAILED</b>.
61                 
62                 <p>
63                 The <b>DISCONNECT</b> message is sent by the client to the server to end the virtual session.  The server
64                 shall not respond to any disconnect messages.
65         
66                 
67                 <h1> Message Layer </h1>
68
69                 <p>
70                 There are currently two types of message layer messages: <b>REQUEST</b> and <b>RESULT</b>.  <b>REQUEST</b>
71                 messages represent application layer requests made by a client and <b>RESULT</b> messages are the servers 
72                 response to such <b>REQUEST</b>'s.
73                 
74                 <p>
75                 By design, all <b>CONNECT</b> and <b>REQUEST</b> messages sent by a client will be acknowledged by one or 
76                 more responses from the server.  This is much like the SYN-ACK philosophy of TCP, however different in many 
77                 ways.  The only guarantees made by the server are 1. you will know that we received your request and 2. you 
78                 will know the final outcome of your request.  It is the responsibility of the actual application to send 
79                 the requested application data (e.g. RESULT messages, intermediate STATUS messages).
80                 
81                 
82                 <p>
83                 The server responses are matched to client requests by a <b>threadTrace</b>.  A threadTrace is simply a 
84                 number and all application layer messages and STATUS messages are required to have one.  (Note that the 
85                 threadTrace contained within a STATUS message sent in response to a CONNECT will be ignored).  Currently, 
86                 there is no restriction on the number other than it shall be unique within a given virtual connection.  
87                 When the server receives a <b>REQUEST</b> message, it extracts the <b>threadTrace</b> from the message 
88                 and all responses to that request will contain the same <b>threadTrace</b>.
89                 
90                 <p>
91                 As mentioned above, every <b>CONNECT</b> message will be acknowledged by a single 
92                 <b>STATUS</b> message.  <b>REQUEST</b>'s are a little more complex, however.  A <b>REQUEST</b> 
93                 will receive one or more <b>RESULT</b>'s if the <b>REQUEST</b> warrants such a response.  A <b>REQUEST</b>
94                 may even receive one or more intermediate <b>STATUS</b>'s (e.g. <b>STATUS_CONTINUE</b>).  (Consult the 
95                 documentation on the application request the client is requesting for more information on the number and 
96                 type of responses to that request).  All <b>REQUEST</b>'s, however, regardless of other response types,
97                 shall receieve as the last response a <b>STATUS</b> message with statusCode <b>STATUS_COMPLETE</b>.  This
98                 allows the client to wait for REQUEST "completeness" as opposed to waiting on or calculating individual 
99                 responses.
100
101
102                 <h1> Client Pseudocode </h1>
103
104                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
105
106 send CONNECT
107
108 msg = recv()
109
110 if ( msg.statusCode == STATUS_OK ) 
111
112         OK. continue
113
114 while ( more requests ) {
115
116         /* you may send multiple requests before processing any responses.  For the sake
117                 of this example, we will only walk through a single client request */
118
119         send REQUEST with threadTrace X 
120
121         while ( response = recv ) { 
122
123                 if (  response.threadTrace != X ) 
124
125                         continue/ignore
126
127                 if ( response.type == STATUS )
128                 
129                         if (  response.statusCode == STATUS_TIMEOUT             or
130                                         response.statusCode == STATUS_REDIRECTED        or
131                                         response.statusCode == STATUS_EXPFAILED)
132
133                                 resend the the request with threadTrace X because it was not honored.
134
135                         if ( response.statusCode == STATUS_COMPLETE ) 
136
137                                 the request is now complete, nothing more to be done with this request
138                                 break out of loop
139         
140                 if ( response.typ == RESULT )
141
142                         pass result to the application layer for processing
143
144         } // receiving
145
146 } // sending
147
148
149                 </pre>
150
151                 <br>
152                 <h1> Server Pseudocode </h1>
153
154                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
155
156 while( message = recv() ) {
157
158         if( message.type != CONNECT )
159
160                 return a STATUS with statusCode STATUS_EXPFAILED
161                 start loop over
162
163         if ( message.type == CONNECT )
164
165                 return STATUS with statusCode STATUS_OK and continue
166
167         while ( msg = recv() and virtual session is active ) {
168
169
170                 if ( msg.type == REQUEST )
171
172                         Record the threadTrace.  Pass the REQUEST to the application layer for processing.
173                         When the application layer has completed processing, respond to the client
174                         with a STATUS message with statusCode STATUS_COMPLETE and threadTrace matching
175                         the threadTrace of the REQUEST.  Once the final STATUS_COMPLETE message is sent,
176                         the session is over.  Return to outer server loop. 
177
178                         /* Note: during REQUEST processing by the application layer, the application may 
179                                 opt to send RESULT and/or STATUS messages to the client.  The server side
180                                 transport mechanism is not concerned with these messages.  The server only 
181                                 needs to be notified when the REQUEST has been sucessfully completed. */
182
183                 if( message.type == DISCONNECT )
184
185                         Virtual session has ended. Return to outer loop.
186
187
188         } // Sessin loop
189
190 } // Main server loop
191
192
193
194                 </pre>
195
196
197                 <br>
198                 <h1> XML Examples</h1>
199                 <br>
200
201
202                 <h2> Protocol Element </h2>
203
204                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
205
206 &lt;oils:domainObjectAttr value="1" name="protocol"/>
207
208                 </pre>
209
210                 <h2> threadTrace Element </h2>
211
212                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
213
214 &lt;oils:domainObjectAttr value="1" name="threadTrace"/>
215
216                 </pre>
217
218                 <h2> CONNECT Message </h2>
219
220                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
221
222 &lt;oils:domainObject name="oilsMessage">
223         &lt;oils:domainObjectAttr value="CONNECT" name="type"/>
224         &lt;oils:domainObjectAttr value="1" name="threadTrace"/>
225         &lt;oils:domainObjectAttr value="1" name="protocol"/>
226 &lt;/oils:domainObject>
227
228                 </pre>
229
230
231                 <h2> DISCONNECT Message </h2>
232
233                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
234
235 &lt;oils:domainObject name="oilsMessage">
236         &lt;oils:domainObjectAttr value="DISCONNECT" name="type"/>
237         &lt;oils:domainObjectAttr value="0" name="threadTrace"/>
238         &lt;oils:domainObjectAttr value="1" name="protocol"/>
239 &lt;/oils:domainObject>
240
241                 </pre>
242
243                 <h2> STATUS Message </h2>
244
245                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
246
247 &lt;oils:domainObject name="oilsMessage">
248         &lt;oils:domainObjectAttr value="STATUS" name="type"/>
249         &lt;oils:domainObjectAttr value="0" name="threadTrace"/>
250         &lt;oils:domainObjectAttr value="1" name="protocol"/>
251         &lt;oils:domainObject name="oilsConnectStatus">
252                 &lt;oils:domainObjectAttr value="Connection Successful" name="status"/>
253                 &lt;oils:domainObjectAttr value="200" name="statusCode"/>
254         &lt;/oils:domainObject>
255 &lt;/oils:domainObject>
256
257                 </pre>
258
259                 <h2> REQUEST Message </h2>
260
261                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
262
263 &lt;oils:domainObject name="oilsMessage">
264         &lt;oils:domainObjectAttr value="REQUEST" name="type"/>
265         &lt;oils:domainObjectAttr value="4" name="threadTrace"/>
266         &lt;oils:domainObjectAttr value="1" name="protocol"/>
267         &lt;oils:domainObject name="oilsMethod">
268                 &lt;oils:domainObjectAttr value="mult" name="method"/>
269                 &lt;oils:params>[1, 2]&lt;/oils:params>
270         &lt;/oils:domainObject>
271 &lt;/oils:domainObject>
272
273                 </pre>
274
275                 <h2> RESULT Message </h2>
276                 
277                 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
278
279 &lt;oils:domainObject name="oilsMessage">
280         &lt;oils:domainObjectAttr value="RESULT" name="type"/>
281         &lt;oils:domainObjectAttr value="4" name="threadTrace"/>
282         &lt;oils:domainObjectAttr value="1" name="protocol"/>
283         &lt;oils:domainObject name="oilsResult">
284                 &lt;oils:domainObjectAttr value="OK" name="status"/>
285                 &lt;oils:domainObjectAttr value="200" name="statusCode"/>
286                 &lt;oils:domainObject name="oilsScalar">2&lt;/oils:domainObject>
287         &lt;/oils:domainObject>
288 &lt;/oils:domainObject>
289
290                 </pre>
291                 
292
293         </body>
294
295 </html>
296
297