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