| <?xml version="1.0" encoding="iso-8859-1"?> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
| "http://www.w3.org/TR/html4/loose.dtd"> |
| <html> |
| <head> |
| <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> |
| <title>Sandesha2 Architecture guide</title> |
| <meta name="generator" content="amaya 9.2.2, see http://www.w3.org/Amaya/" |
| /> |
| </head> |
| |
| <body> |
| <h2>Introduction</h2> |
| |
| <p>Sandesha2 implements WS-ReliableMessaging for Axis2. From the point of |
| view of the Axis2 engine, Sandesha2 is a module. When this module is engaged |
| to a service, that service get reliable messaging capability. According to |
| the WS-ReliableMessaging specification reliable communication happens between |
| two endpoints. These two are called the RM Source and the RM Destination. |
| Before communication, RM Source and RM Destination do a message exchange to |
| create something called a sequence. A sequence is always identified by a |
| unique sequenceID. The messages of a sequence are numbered starting from |
| one.</p> |
| |
| <p>The reliability is obtained basically using acknowledgements. the RM |
| Source is required to send each messages one or more times. RM Destination |
| send back acknowledgements to notify the successful reception of messages. |
| After receiving the acknowledgement for a certain message RM Source can stop |
| the retransmission of that message.</p> |
| |
| <p>When all messages of a certain sequence have been successfully transmitted |
| to the RM Destination, RM Source sends a TerminateSequence message to the RM |
| Destination. If RM Destination receive this it can free any resources |
| allocated for this sequence.</p> |
| |
| <p></p> |
| |
| <p>Folliwing popular diagram explains the most basic operations of the RM |
| Source and the RM Destination.</p> |
| |
| <p><img alt="WS-RM Model" src="images/RMModel.jpg" /></p> |
| |
| <p>Application Source which is basically the client code gives the messages |
| to the RM Source. RM Source first does the initial message exchange with the |
| RM Destination and establish a sequence. After that RM Source send the |
| messages one or more times. RM Destination send back Acknowledgements. After |
| receiving acknowledgements for all the messages RM Source will send a |
| TerminateSequence message to the RM Destination.</p> |
| |
| <p></p> |
| |
| <p>RM Destination will obtain the messages and invoke them by passing to the |
| Application Destination. If RM Destination is configured to invoke the |
| messages in order, it will have to pause the invocation of some messages |
| until all previous once have been received and invoked.</p> |
| |
| <p></p> |
| |
| <p></p> |
| |
| <h2>Basic Architecture of Sandesha2</h2> |
| |
| <p></p> |
| |
| <p><img alt="Basic Architecture" src="images/basicArchitecture.png" /></p> |
| |
| <p></p> |
| |
| <p>Above diagram gives the basic architecture of Sandesha2. Let's try to |
| understand each part of this in detail.</p> |
| |
| <p></p> |
| |
| <h3>Handlers</h3> |
| |
| <p>Sandesha module deploy three handlers into Axis2 phases.</p> |
| |
| <p>1. SandeshaOutHandler</p> |
| |
| <p>2. SandeshaInHandler</p> |
| |
| <p>3.SandeshaGlobalInHandler</p> |
| |
| <p></p> |
| |
| <p>SandesOutHandler is the only handler added to the outFlow by the Sandesha2 |
| module. This handler stops the out going application messages till a sequence |
| is established. The handler is deployed to the RMPhase of the outFlow.</p> |
| |
| <p></p> |
| |
| <p>SandeshaGlobalInHandler is deployed to the predispatch phase (of inFlow) |
| when the RMModule is engaged. So this get called for all the messages that |
| come to Axis2. This does functions that should be performed globally such as |
| duplicate detection.</p> |
| |
| <p></p> |
| |
| <p>SandeshaInHandler is the second handler of the inFlow. Since this is |
| situated in the RMPhase which comes after the dispatch phase, this handler |
| get called only for messages that come to RM enabled services.</p> |
| |
| <p></p> |
| |
| <h3>Sender</h3> |
| |
| <p>Sender is responsible for transmition and retransmition of messages. The |
| Sender is a seperate thread that keeps running all the time. At each |
| iteration Sender check the Sandesha2 Storage to see weather there are any |
| messages to be sent. If there are any, they are sent. If a message does not |
| have to be retransmitted the Sender delete this entry from the Storage. |
| Otherwise the entry is only modified, and will be sent at some other time. |
| How exactly this happens will be explained later.</p> |
| |
| <p></p> |
| |
| <h3>Message Processors</h3> |
| |
| <p>Sandesha2 have a set of message processors each extending the |
| MessageProcessor interface. Each message processor is responsible for |
| processing a certain type of message. For example CreateSequenceProcessor |
| will process incoming Create Sequence messages and Acknowledgement processor |
| will process incoming Acknowledgement messages. Please check the class |
| diagram to see all the MessageProcessors.</p> |
| |
| <p></p> |
| |
| <h3>InOrderInvoker</h3> |
| |
| <p>InOrderInvoker is another seperate thread that get started by the |
| Sandesha2 system. This is started only if Sadesha2 has been configured to |
| support InOrder Invocation delivery assurance. InOrderInvoker is responsible |
| for invoking messages of a sequence in the order of message numbers.</p> |
| |
| <p></p> |
| |
| <h3>Sandesha2 Storage Framework</h3> |
| |
| <p>Sandesha2 Storage Framework cab be given as the cornerstone of Sandesha2 |
| system. This was designed to support the RM Message exchage while being |
| independent of the storage implementation used. Two main storage |
| implementations are InMemory storage implementation and Database based |
| storage implementation.</p> |
| |
| <p>Storage framework define several beans that extend the RMBean storage (so |
| these are called RM Beans). Currently there are five RM Beans. They are.</p> |
| <ol> |
| <li>CreateSequenceBean (fields - InternalSequenceID, CreateSequenceMsgID, |
| SequenceID)</li> |
| <li>SenderBean (fields - key, internalSequenceID, msgNo, msgID, msgType, |
| send, resent, sentCount)</li> |
| <li>NextMsgBean (fields - sequenceID, nextMsgToInvoke)</li> |
| <li>InvokerBean (fields - key, sequenceID, msgNo)</li> |
| <li>SequencePropertyBean (fields - sequenceID, propertyName, |
| propertyValue)</li> |
| </ol> |
| |
| <p>Each storage implementation should have five BeanManagers that define how |
| to manage each of these beans. There are five BeanManager interaces that |
| define how the managers should be defined. Also there is a StorageManager |
| interface that define methods to create each of these BeanManagers. Another |
| interface called Transaction has general transaction methods like commit and |
| roleback.</p> |
| |
| <p>Collectively each Sandesha2 storage implementation should have following |
| classes.</p> |
| <ol> |
| <li>An implementation of the StorageManager interface.</li> |
| <li>Implementations of five Bean Manager interfaces.</li> |
| <li>An implementation of a transaction interface.</li> |
| </ol> |
| |
| <p>After implementing these the user has to add these to the classpath (may |
| be as a jar) and include the name of the StorageManager implementation class |
| in the sandesha2.properties file. This will tell Sandesha2 to use this |
| storage implementation as the default (this will need a restart of the Axis2 |
| engine).</p> |
| |
| <p></p> |
| |
| <h3>Delivery Assurances</h3> |
| |
| <p>You can instruct Sandesha2 to give the delivery assurance you want. The |
| bacis configurable delivery assurance we provide is the odering of messages. |
| By setting the InOrderInvocation property of Sandesha2.properties file to |
| true (the default), you can tell Sandesha2 to invoke messages of a sequence |
| in the order. Order will be decided based on the wsrm:messageNumber. If you |
| set this property to false, Sandesha2 will invoke messages as they come. |
| Please note that if you set an invalid value to this property, Sandesha2 will |
| use the defult.</p> |
| |
| <p>Which delivery assurance to use depend on your requirements. If you want |
| want the invocation to be as fast as possible and if you do not care about |
| ordering, set the property to false. If you want ordering, set it to true. |
| There could be a considerable performance improvement if you set this to |
| false.</p> |
| |
| <p>Internally sandesha2 start a special thread if in-order invocation is |
| required (InOrderInvoker). This thread which is continuously running will |
| only invoke the messages in order.</p> |
| |
| <p>In the current implementation each message (identified by sequenceID and |
| message number) will be invoked only once. So exactly once delivey assurance |
| is guaranteed. You cannot ask Sandesha2 to invoke the same message more than |
| once.</p> |
| |
| <p></p> |
| |
| <h2>Example Scenario</h2> |
| |
| <p>This part explains how Sandesha2 framework work internally for the most |
| common RM scenario. Which is the sending of a couple of Ping messages from a |
| client to the server. We will mailnly look at how Sandesha2 use its storage |
| to do the RM message exchange correctly. While reading this please keep in |
| mind the RM Beans and their fields which were mentioned before.</p> |
| |
| <p><b>Client side</b></p> |
| <ul> |
| <li>Client invoke the call.</li> |
| <li>SandeshaOutHandler pauses the message and create a new Create Sequence |
| Request message.</li> |
| <li>SandeshaOutHandler adds an entry to the CreateSequenceBeanManager. The |
| internalSequenceId is an identifier unique to the whole sequence. For the |
| client side this is the concantination of wsa:To and a constants set by |
| the client (SEQUENCE_KEY). The seqenceID property is initially null. The |
| createSeqMsgID is the message ID of the crerated Create Sequence |
| message.</li> |
| <li>SandeshaOutHandler adds two entries to the SenderBeanManager. One which |
| has the send property to false represents the application message. Other |
| which has the send property to true represents the Create Sequence |
| message. The Sender threads sends (and retransmits) only the Create |
| Sequence message.</li> |
| <li><p>Sometime later the client side receives an Create Sequence Response |
| message from the server. The SandeshaInHandler which is the Sandesha2 |
| handler in the InFlow finds this and delegates the processing to the |
| CreateSequenceResponse message processor. It finds the correct |
| CreateSequence manager entry using the createSequenceMessageID property |
| (the value of the create sequence message ID comes in the relatesTo part |
| of the Create Sequence Response message).</p> |
| </li> |
| <li>Client update the sequenceID property of the CreateSequence BeanManager |
| entry. Also the send value of the application message entries are set to |
| true, so that the sender start sending (and retransmitting) them.</li> |
| <li>When the client receive acknowlegements for the messages it sent, the |
| task is deligate to the Acknwoledgement processor, It removes the |
| corresponsing entry of that application message ifrom the |
| SenderBeanManager.</li> |
| <li>If an acknowledgement says that all the sent messages (upto last |
| message) were successfully received, the Acknowledgement processor |
| creates an TerminateSequence message and adds an corresponding entry to |
| the Sender table.</li> |
| </ul> |
| |
| <p><b>Server side</b></p> |
| <ul> |
| <li>Server receives an CreateSequence message. It generates a new sequence |
| ID and creates a new CreateSequenceResponse message containing this.</li> |
| <li>Server adds an entry to the NextMessage Bean manager. The initial velue |
| for nextMessageToInvoke is 1.</li> |
| <li>Server adds an entry to the Sender bean manager (of server side) |
| representing the application message. The send value is true. The Create |
| Sequence Responese message is sent by the Sender.</li> |
| <li>After some time the server receives an application message. The server |
| side SandeshaInHandler delegates this to the ApplicationMessageProcessor |
| which creates an Acknowledgement and send it. If InOrder invocation is |
| enabled, an entry is added to the InvokerBeanManager representing this. |
| (suppose the message number of this message is 2)</li> |
| <li>The InOrderInvoker which keeps looking at the InvokerBeanManager |
| entries sees that there are entries to be invoked.</li> |
| <li>the InOrderInvoker checks the entry of the NextMessageBeanManager of |
| the relevent sequence and sees that it is 1. But since only message |
| number 2 is present in the invokerBeanManager entries the invocation is |
| not done.</li> |
| <li>After some time application message 1 also comes. Now the Invoker sees |
| this entry and invoke the message. It also update the |
| NextMessageBeanManager nextMessageToInvoke property to 2. The invoker |
| again check weather the new entry for the NextMessageToInvoke (2) is |
| present in the InvokerBeanManager entries. Since this is present it is |
| also invoked. The value is again updated (to 3) but no invocation is done |
| since an entry is not found.</li> |
| <li>Some time later the server may receive an TerminateSequence message. It |
| can partly remove the resources allocated for the sequence. Other part |
| (which is required by the InOrderInvoker) is removed after the invocation |
| of the last message.</li> |
| </ul> |
| |
| <p></p> |
| |
| <p></p> |
| </body> |
| </html> |