5 <title> OILS Messaging </title>
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.
20 All messages must declare which protocol version they are requesting. The current protocol level
23 <h1> Transport Layer </h1>
26 There are currently three types of messages in the transport layer: <b>CONNECT, STATUS, </b> and
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:
38 <b> <pre style="border: solid thin blue; margin: 2% 10% 2% 10%; padding-left: 50px">
52 This list is likely to change at least a little.
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
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>.
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.
69 <h1> Message Layer </h1>
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.
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).
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>.
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
104 <h1> Client Pseudocode </h1>
106 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
112 if ( msg.statusCode == STATUS_OK )
116 while ( more requests ) {
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 */
121 send REQUEST with threadTrace X
123 while ( response = recv ) {
125 if ( response.threadTrace != X )
129 if ( response.type == STATUS )
131 if ( response.statusCode == STATUS_TIMEOUT or
132 response.statusCode == STATUS_REDIRECTED or
133 response.statusCode == STATUS_EXPFAILED)
135 resend the the request with threadTrace X because it was not honored.
137 if ( response.statusCode == STATUS_COMPLETE )
139 the request is now complete, nothing more to be done with this request
142 if ( response.type == RESULT )
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
150 pass result to the application layer for processing
160 <h1> Server Pseudocode </h1>
162 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
164 while( message = recv() ) {
166 if( message.type != CONNECT )
168 return a STATUS with statusCode STATUS_EXPFAILED
171 if ( message.type == CONNECT )
173 return STATUS with statusCode STATUS_OK and continue
175 while ( msg = recv() and virtual session is active ) {
178 if ( msg.type == REQUEST )
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.
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. */
191 if( message.type == DISCONNECT )
193 Virtual session has ended. Return to outer loop.
198 } // Main server loop
206 <h1> XML Examples</h1>
210 <h2> Protocol Element </h2>
212 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
214 <oils:domainObjectAttr value="1" name="protocol"/>
218 <h2> threadTrace Element </h2>
220 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
222 <oils:domainObjectAttr value="1" name="threadTrace"/>
226 <h2> CONNECT Message </h2>
228 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
230 <oils:domainObject name="oilsMessage">
231 <oils:domainObjectAttr value="CONNECT" name="type"/>
232 <oils:domainObjectAttr value="1" name="threadTrace"/>
233 <oils:domainObjectAttr value="1" name="protocol"/>
234 </oils:domainObject>
239 <h2> DISCONNECT Message </h2>
241 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
243 <oils:domainObject name="oilsMessage">
244 <oils:domainObjectAttr value="DISCONNECT" name="type"/>
245 <oils:domainObjectAttr value="0" name="threadTrace"/>
246 <oils:domainObjectAttr value="1" name="protocol"/>
247 </oils:domainObject>
251 <h2> STATUS Message </h2>
253 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
255 <oils:domainObject name="oilsMessage">
256 <oils:domainObjectAttr value="STATUS" name="type"/>
257 <oils:domainObjectAttr value="0" name="threadTrace"/>
258 <oils:domainObjectAttr value="1" name="protocol"/>
259 <oils:domainObject name="oilsConnectStatus">
260 <oils:domainObjectAttr value="Connection Successful" name="status"/>
261 <oils:domainObjectAttr value="200" name="statusCode"/>
262 </oils:domainObject>
263 </oils:domainObject>
267 <h2> REQUEST Message </h2>
269 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
271 <oils:domainObject name="oilsMessage">
272 <oils:domainObjectAttr value="REQUEST" name="type"/>
273 <oils:domainObjectAttr value="4" name="threadTrace"/>
274 <oils:domainObjectAttr value="1" name="protocol"/>
275 <oils:domainObject name="oilsMethod">
276 <oils:domainObjectAttr value="mult" name="method"/>
277 <oils:params>[1, 2]</oils:params>
278 </oils:domainObject>
279 </oils:domainObject>
283 <h2> RESULT Message </h2>
285 <pre style="border: solid thin blue; margin: 0% 10% 0% 10%; padding-left: 50px">
287 <oils:domainObject name="oilsMessage">
288 <oils:domainObjectAttr value="RESULT" name="type"/>
289 <oils:domainObjectAttr value="4" name="threadTrace"/>
290 <oils:domainObjectAttr value="1" name="protocol"/>
291 <oils:domainObject name="oilsResult">
292 <oils:domainObjectAttr value="OK" name="status"/>
293 <oils:domainObjectAttr value="200" name="statusCode"/>
294 <oils:domainObject name="oilsScalar">2</oils:domainObject>
295 </oils:domainObject>
296 </oils:domainObject>