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