Added: webservices/sandesha/trunk/java/xdocs/userGuide.html URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/xdocs/userGuide.html?rev=414476&view=auto ============================================================================== --- webservices/sandesha/trunk/java/xdocs/userGuide.html (added) +++ webservices/sandesha/trunk/java/xdocs/userGuide.html Wed Jun 14 22:51:15 2006 @@ -0,0 +1,966 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> + <title>Sandesha2 User Guide</title> + <meta name="generator" content="amaya 9.2.1, see http://www.w3.org/Amaya/" + /> +</head> + +<body xml:lang="en"> +<h1>Apache Sandesha2 User's Guide</h1> + +<p>This document introduces you to Apache Sandesha2. This will first take you +through a step by step process of developing a sample application using +Sandesha2. In the latter sections you will be introduced to some advance +features making you more familiar with the application.</p> + +<h2>Contents</h2> +<ul> + <li><a href="#intro">Introduction</a></li> + <li><a href="#yfs">Your First Service with Sandesha2</a></li> + <li><a href="#wcfr">Writing Clients for Reliable Services</a> + <ul> + <li><a href="#oneway">Client Code for a One-Way RM Service Call</a></li> + <li><a href="#requestreply">Client code for a Request-Reply RM Service + Call</a></li> + </ul> + </li> + <li><a href="#acs">Advance Client Scenarios</a> + <ul> + <li><a href="#gaa">Getting Acknowledgements and Faults to a given + Endpoint</a></li> + <li><a href="#ms">Managing Sequences</a></li> + <li><a href="#oas">Offering a Sequence ID for the Response + Sequence</a></li> + <li><a href="#cras">Creating a Sequence Without Sending any + Messages</a></li> + <li><a href="#sar">Sending Acknowledgement Requests from the Client + Code</a></li> + <li><a href="#sts">Selecting the Specification Version which you want + to Work in</a></li> + <li><a href="#tas">Terminating a Sequence from the Client Code</a></li> + <li><a href="#clas">Closing a Sequence from the Client Code</a></li> + <li><a href="#btc">Blocking the Client Code until a Sequence is + Complete</a></li> + </ul> + </li> + <li><a href="#smo">Sequence Management of Sandesha2</a> + <ul> + <li><a href="#san">Starting a New Sequence</a></li> + <li><a href="#tas">Terminating a Sequence</a></li> + <li><a href="#cas">Closing a Sequence</a></li> + <li><a href="#toa">Timing Out a Sequence</a></li> + </ul> + </li> + <li><a href="#wws">Working with Sandesha Reports</a> + <ul> + <li><a href="#sandeshareport">SandeshaReport</a></li> + <li><a href="#sequencereport">SequenceReport</a></li> + </ul> + </li> + <li><a href="#slf">Sandesha Listener Feature</a> + <ul> + <li><a href="#onerror">onError</a></li> + <li><a href="#ontimeout">onTimeOut</a></li> + </ul> + </li> + <li><a href="#dao">Delivery Assurances of Sandesha2</a></li> + <li><a href="#cs">Configuring Sandesha2</a> + <ul> + <li><a href="#acknowledgementinterval">AcknowledgementInterval</a></li> + <li><a href="#retransmissioninterval">RetransmissionInterval</a></li> + <li><a href="#exponentialbackoff">ExponentialBackoff</a></li> + <li><a + href="#maximumretransmissioncount">MaximumRetransmissionCount</a></li> + <li><a href="#inactivitytimeout">InactivityTimeout</a></li> + <li><a + href="#inactivitytimeoutmeasure">InactivityTimeoutMeasure</a></li> + <li><a href="#invokeinorder">InvokeInOrder</a></li> + <li><a href="#storagemanager">StorageManager</a></li> + <li><a href="#messagetypestodrop">MessageTypesToDrop</a></li> + </ul> + </li> +</ul> +<a name="intro"></a> +<h2>Introduction</h2> + +<p>Sandesha2 is a Web Service-ReliableMessaging (WS-RM) implementation for +Apache Axis2. With Sandesha2 you can make your Web services reliable, or you +can invoke already hosted reliable Web services.</p> + +<p>If you want to learn more about Apache Axis2, refer to <a +href="http://ws.apache.org/axis2/0_95/userguide.html" target="_blank">Apache Axis2 User +Guide</a> and <a +href="http://ws.apache.org/axis2/0_95/Axis2ArchitectureGuide.html" target="_blank">Apache +Axis2 Architecture Guide</a>.</p> + +<p>If you want to know about the design of Sandesha2 refer to <a +href="architectureGuide.html" target="_blank">Sandesha2 Architecture Guide</a>.</p> + +<p> +Sandesha2 supports the WS-ReliableMessaging specification. It fully supports the WS-ReliableMessaging +1.0 specification (February 2005) +(<a href="http://specs.xmlsoap.org/ws/2005/02/rm/ws-reliablemessaging.pdf"> +http://specs.xmlsoap.org/ws/2005/02/rm/ws-reliablemessaging.pdf + </a>). + +</p> +<p> +This specification has been submitted to OASIS and currently being standardized under the OASIS WS-RX +Technical Committee as WSRM 1.1 (see +<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ws-rx"> +http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ws-rx +</a> ). +Sandesha2 currently supports Committee Draft 3 of the specification being developed under this +technical committee ( +<a href="http://docs.oasis-open.org/ws-rx/wsrm/200602/wsrm-1.1-spec-cd-03.pdf"> +http://docs.oasis-open.org/ws-rx/wsrm/200602/wsrm-1.1-spec-cd-03.pdf +</a>). +</p> + +<a name="yfs"></a> +<h2>Your First Service with Sandesha2</h2> + +<p>This section will give you step by step guidelines on creating a Web +service with reliability and making it available within your Axis2 server. +This simple service will have a single one-way operation (ping) and a +request-response operation (echoString).</p> + +<p>The steps are as follows:"</p> + +<p>1. Download the Axis2 Webapp distribution (Axis2.war file) and deploy it +within Tomcat. Extract the webapp so that you can edit the files of the +webapp. (this will also be done if you run tomcat with the axis2.war file +within the webapps folder).</p> + +<p>2. Add a user phase named RMPhase to the inFlow, outFlow of inFaultFlow of +the axis2.xml file which is situated under the webapps/axis2/WEB-INF/conf +directory. The 'Phases' part of a axis2.xml file with RMPhase is given +below.</p> +<pre><axisconfig name="AxisJava2.0"> + <!-- OTHER PARTS OF THE CONFIGURATOIN--> + <phaseOrder type="inflow"> + <phase name="Transport"> + <!-- TRANSPORT PHASE HANDLERS--> + </phase> + <phase name="Security"/> + <phase name="PreDispatch"/> + <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> + <!-- DISPATCH PHASE HANDLERS--> + </phase> + <phase name="OperationInPhase"/> + <phase name="RMPhase"/> + </phaseOrder> + <phaseOrder type="outflow"> + <phase name="RMPhase"/> + <phase name="OperationOutPhase"/> + <phase name="PolicyDetermination"/> + <phase name="MessageOut"/> + </phaseOrder> + <phaseOrder type="INfaultflow"> + <phase name="PreDispatch"/> + <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> + <!-- DISPATCH PHASE HANDLERS--> + </phase> + <phase name="OperationInFaultPhase"/> + <phase name="RMPhase"/> + </phaseOrder> + <phaseOrder type="Outfaultflow"> + <!-- user can add his own phases to this area --> + <phase name="RMPhase"/> + <phase name="OperationOutFaultPhase"/> + <phase name="PolicyDetermination"/> + <phase name="MessageOut"/> + </phaseOrder> +</axisconfig></pre> + +<p>2 Get a Sandesha2 binary distribution. Extract this to obtain the sandesha +module file (which has the format sandesha2-<VERSION>.mar). Put this to +the webapps/axis2/WEB-INF/modules directory.</p> + +<p>3. Create the service implementation java file as given below. Compile +this after adding all the libraries within the webapps/axis2/WEB-INF/lib +directory to your classpath.</p> + +<p><em><strong>RMSampleService.java</strong></em></p> +<pre>package sandesha2.samples.userguide; + +import java.util.HashMap; +import java.util.Map; +import javax.xml.namespace.QName; +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.OMFactory; +import org.apache.axiom.om.OMNamespace; + +public class RMSampleService { + + private static Map sequenceStrings = new HashMap(); //TODO make this non static + private final String applicationNamespaceName = "http://tempuri.org/"; + private final String Text = "Text"; + private final String Sequence = "Sequence"; + private final String echoStringResponse = "echoStringResponse"; + private final String EchoStringReturn = "EchoStringReturn"; + + public OMElement echoString(OMElement in) throws Exception { + + OMElement textElem = in.getFirstChildWithName(new QName (applicationNamespaceName,Text)); + OMElement sequenceElem = in.getFirstChildWithName(new QName (applicationNamespaceName,Sequence)); + + if (textElem==null) + throw new Exception ("'Text' element is not present as a child of the 'echoString' element"); + if (sequenceElem==null) + throw new Exception ("'Sequence' element is not present as a child of the 'echoString' element"); + + String textStr = textElem.getText(); + String sequenceStr = sequenceElem.getText(); + + System.out.println("'EchoString' service got text '" + textStr + "' for the sequence '" + sequenceStr + "'"); + + String previousText = (String) sequenceStrings.get(sequenceStr); + String resultText = (previousText==null)?textStr:previousText+textStr; + sequenceStrings.put(sequenceStr,resultText); + + OMFactory fac = OMAbstractFactory.getOMFactory(); + OMNamespace applicationNamespace = fac.createOMNamespace(applicationNamespaceName,"ns1"); + OMElement echoStringResponseElem = fac.createOMElement(echoStringResponse, applicationNamespace); + OMElement echoStringReturnElem = fac.createOMElement(EchoStringReturn, applicationNamespace); + + echoStringReturnElem.setText(resultText); + echoStringResponseElem.addChild(echoStringReturnElem); + + return echoStringResponseElem; + } + + public void ping(OMElement in) throws Exception { + OMElement textElem = in.getFirstChildWithName(new QName (applicationNamespaceName,Text)); + if (textElem==null) + throw new Exception ("'Text' element is not present as a child of the 'Ping' element"); + + String textValue = textElem.getText(); + + System.out.println("ping service got text:" + textValue); + } +}</pre> + +<p>4. Create the services.xml service configiration file as given below. Note +that this has engaged the sandesha2 module for this service.</p> + +<p><em><strong>services.xml</strong></em></p> +<pre><service name="RMSampleService"> + <parameter name="ServiceClass" locked="xsd:false">sandesha2.samples.userguide.RMSampleService</parameter> + + <module ref="sandesha2" /> + + <description> + The userguide Sample service. + </description> + + <operation name="ping" mep="http://www.w3.org/2004/08/wsdl/in-only"> + <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver" /> + </operation> + <operation name="echoString"> + <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver" /> + </operation> +</service></pre> + +<p>5. Set RMSampleService.class and the services.xml files obtained from the +previous steps in the folder structure below. Create a RMInteropService.aar +file by compressing it using the jar tool.</p> +<pre>----META-INF +--------services.xml +----sandesha2 +-------samples +-----------userguide +---------------RMSampleService.class</pre> + +<p>6. Deploy the service by dropping it to the webapp/axis2/WEB-INF/services +directory.</p> + +<p>Now your service is deployed with reliable messaging capability!</p> +<a name="wcfr"></a> +<h2>Writing Clients for Reliable Services</h2> + +<p>1. Create a repository folder in your file system (let's call it Client_Repo).</p> + +<p>2.Put the client_axis2.xml file that comes with the Sandesha2 +distributions to the Client_Repo.</p> + +<p>3. Create a sub folder named 'modules' in the Client Repo and add the +sandesha and addressing module files to that. Your folder structure should +look like following now.</p> +<pre>-- Client_Repo +------ client_axis2.xml +-------modules +-------------sandesha2.mar +-------------addressing.mar</pre> + +<p>4. Write your client code as given in the following example scenarios. In +these scenarios the variable CLIENT_REPO_PATH should be given the full path +to the Client Repo folder in a java compatible manner. To compile these you +will have to add all the library files that come with the Axis2 distribution +and the sandesha2-client-<VERSION>.jar file to your classpath.</p> + +<p>For e.g.:</p> +<pre>CLIENT_REPO_PATH = c:\\sandesha2\\repository</pre> + +<a name="oneway"></a> +<p><b>Client Code for a One-Way RM Service Call</b></p> + +<p><em><strong>UserguidePingClient.java</strong></em></p> +<pre>package sandesha2.samples.userguide; + +import java.io.File; +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.OMFactory; +import org.apache.axiom.om.OMNamespace; +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.EndpointReference; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.ConfigurationContextFactory; +import org.apache.sandesha2.client.SandeshaClientConstants; + + +public class UserguidePingClient { + + private static final String applicationNamespaceName = "http://tempuri.org/"; + private static final String ping = "ping"; + private static final String Text = "Text"; + private static String toEPR = "http://127.0.0.1:8080/axis2/services/RMSampleService"; + private static String CLIENT_REPO_PATH = "Full path to the Client Repo folder"; + + public static void main(String[] args) throws AxisFault { + + String axis2_xml = CLIENT_REPO_PATH + File.separator + "client_axis2.xml"; + ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(CLIENT_REPO_PATH,axis2_xml); + + Options clientOptions = new Options (); + clientOptions.setTo(new EndpointReference (toEPR)); + + ServiceClient serviceClient = new ServiceClient (configContext,null); + clientOptions.setAction("urn:wsrm:Ping"); + serviceClient.setOptions(clientOptions); + +// serviceClient.engageModule(new QName ("sandesha2")); +// serviceClient.engageModule(new QName ("addressing")); + + serviceClient.fireAndForget(getPingOMBlock("ping1")); + serviceClient.fireAndForget(getPingOMBlock("ping2")); + + clientOptions.setProperty(SandeshaClientConstants.LAST_MESSAGE, "true"); + serviceClient.fireAndForget(getPingOMBlock("ping3")); + + serviceClient.finalizeInvoke(); + } + + private static OMElement getPingOMBlock(String text) { + OMFactory fac = OMAbstractFactory.getOMFactory(); + OMNamespace namespace = fac.createOMNamespace(applicationNamespaceName,"ns1"); + OMElement pingElem = fac.createOMElement(ping, namespace); + OMElement textElem = fac.createOMElement(Text, namespace); + + textElem.setText(text); + pingElem.addChild(textElem); + + return pingElem; + } +}</pre> + +<p><em>Let's find out the differences between this code and a client code +without RM:</em></p> + +<p>You have to engage the sandesha and addressing modules. This has to be +done only if your axis2.xml file does not globally add these. For example, if +you are using the axis2_client.xml as in the previous file that comes with +the Sandesha2 distribution, these two lines have to be omitted (as done in the previous +code example). Otherwise Axis2 will throw the exception "org.apache.axis2.AxisFault: +Trying to engage a module which is already engaged".</p> +<a name="lastmessage"></a> +<p>Before the last invocation you have to set the LAST_MESSAGE property. +Otherwise the sequence will not terminate properly.</p> +<a name="requestreply"></a> + +<p><b>Client Code for a Request-Reply RM Service Call</b></p> + +<p><strong><em>UserguideEchoClient.java</em></strong></p> +<pre>package sandesha2.samples.userguide; + +import java.io.File; +import javax.xml.namespace.QName; +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.OMFactory; +import org.apache.axiom.om.OMNamespace; +import org.apache.axiom.soap.SOAPBody; +import org.apache.axis2.Constants; +import org.apache.axis2.addressing.EndpointReference; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.client.async.AsyncResult; +import org.apache.axis2.client.async.Callback; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.ConfigurationContextFactory; +import org.apache.sandesha2.client.SandeshaClientConstants; + +public class UserguideEchoClient { + + private final static String applicationNamespaceName = "http://tempuri.org/"; + private final static String echoString = "echoString"; + private final static String Text = "Text"; + private final static String Sequence = "Sequence"; + private final static String echoStringResponse = "echoStringResponse"; + private final static String EchoStringReturn = "EchoStringReturn"; + private static String toEPR = "http://127.0.0.1:8080/axis2/services/RMSampleService"; + + private static String CLIENT_REPO_PATH = "Full path to the Client Repo folder"; + + public static void main(String[] args) throws Exception { + + String axis2_xml = CLIENT_REPO_PATH + File.separator +"client_axis2.xml"; + ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(CLIENT_REPO_PATH,axis2_xml); + ServiceClient serviceClient = new ServiceClient (configContext,null); + + Options clientOptions = new Options (); + clientOptions.setTo(new EndpointReference (toEPR)); + clientOptions.setTransportInProtocol(Constants.TRANSPORT_HTTP); + clientOptions.setUseSeparateListener(true); + serviceClient.setOptions(clientOptions); + +// serviceClient.engageModule(new QName ("sandesha2")); +// serviceClient.engageModule(new QName ("addressing")); + + Callback callback1 = new TestCallback ("Callback 1"); + serviceClient.sendReceiveNonBlocking (getEchoOMBlock("echo1","sequence1"),callback1); + Callback callback2 = new TestCallback ("Callback 2"); + serviceClient.sendReceiveNonBlocking(getEchoOMBlock("echo2","sequence1"),callback2); + + clientOptions.setProperty(SandeshaClientConstants.LAST_MESSAGE, "true"); + Callback callback3 = new TestCallback ("Callback 3"); + serviceClient.sendReceiveNonBlocking(getEchoOMBlock("echo3","sequence1"),callback3); + + while (!callback3.isComplete()) { + Thread.sleep(1000); + } + + Thread.sleep(4000); + } + + private static OMElement getEchoOMBlock(String text, String sequenceKey) { + OMFactory fac = OMAbstractFactory.getOMFactory(); + OMNamespace applicationNamespace = fac.createOMNamespace(applicationNamespaceName,"ns1"); + OMElement echoStringElement = fac.createOMElement(echoString, applicationNamespace); + OMElement textElem = fac.createOMElement(Text,applicationNamespace); + OMElement sequenceElem = fac.createOMElement(Sequence,applicationNamespace); + + textElem.setText(text); + sequenceElem.setText(sequenceKey); + echoStringElement.addChild(textElem); + echoStringElement.addChild(sequenceElem); + + return echoStringElement; + } + + static class TestCallback extends Callback { + + String name = null; + public TestCallback (String name) { + this.name = name; + } + + public void onComplete(AsyncResult result) { + SOAPBody body = result.getResponseEnvelope().getBody(); + + OMElement echoStringResponseElem = body.getFirstChildWithName(new QName (applicationNamespaceName,echoStringResponse)); + OMElement echoStringReturnElem = echoStringResponseElem.getFirstChildWithName(new QName (applicationNamespaceName,EchoStringReturn)); + + String resultStr = echoStringReturnElem.getText(); + System.out.println("Callback '" + name + "' got result:" + resultStr); + } + + public void onError (Exception e) { + System.out.println("Error reported for test call back"); + e.printStackTrace(); + } + } +}</pre> + +<p><em><strong>Here the differences from a normal request-reply client code +is as follows:</strong></em></p> + +<p>Follow the instructions in the previous scenario to do the module +engagement correctly.</p> + +<p>You have to tell Axis2 to use a separate channel for the responses by +using 'useSeperateListner' method of the options object. Also make sure that +you set the incoming transport protocol using the 'setTransportInProtocol' +method.</p> + +<p>Also you have to set the LAST_MESSAGE property as explained in the +previous scenario.</p> + +<p>In the current implementation you are not able to get single channel +responses with Sandesha2. Because of this if you expect a response message, +you must have a return endpoint accessible from the server side. But making +two channel blocking invocations is perfectly valid. But make sure that you +have set a suitable timeout interval in your options object.</p> + +<a name="acs"></a> +<h2>Advance Client Scenarios</h2> + +<p>This section will introduce you to some Client API features which you may +not use for general cases. These features will be useful if you have some +knowledge in WSRM (Web service Reliable Messaging) and if you want to +customize the default behavior of Sandesha2 to make it work according to your +requirements. Some of these have to be done by simply setting a property in +the 'Options' object which you set to your ServiceClient. For these you have +to add the sandesha2-client-<VERSION>.jar to your classpath. For +others, you have to use a special class called SandeshaClient, which is +available in the Sandesha-<VERSION>.jar file. Both these comes with +Sandesha2 distributions.</p> +<a name="gaa"></a> +<h3><b>Getting Acknowledgements and Faults to a Given Endpoint</b></h3> + +<p>In the default configuration, response path for acknowledgements and +faults related to a sequence is the anonymous endpoint. For example, HTTP +transport will send acknowledgements and faults in the HTTP response of +request messages. If you want to avoid this and if you want to get +acknowledgements and faults to a different endpoint, add following part to +the client code before doing any invocation. Note that this does not effect +the path of your application level faults. Only RM faults which occur within +the Sandesha2 will be sent to this endpoint.</p> +<pre>clientOptions.setProperty(SandeshaClientConstants.AcksTo,<endpoint>); //example endpoint - http://tempuri.org/acks.</pre> +<a name="ms"></a> +<h3><b>Managing Sequences</b></h3> + +<p>In the default behaviour Sandesha2 assumes that messages going to the same +endpoint should go in the same RM sequence. Messages will be sent in +different RM sequences only if their WS-Addressing To address is different. +But if required you can instruct Sandesha2 to even send messages that have +the same WS-Addressing To address in two or more sequences. To do this you +have to set a property called Sequence Key.</p> +<pre>clientOptions.setProperty(SandeshaClientConstants.SEQUENCE_KEY,<a string to identify the sequence>);</pre> + +<p>If the sequence key is different, Sandesha2 will send messages in two +sequences even if they are sent to the same endpoint.</p> +<a name="oas"></a> +<h3>Offering a Sequence ID for the Response Sequence</h3> + +<p>This is a concept of reliable messaging which may not be very useful to +you as a end user. Here what you do is offering a sequence ID for the +sequence to be created in the response side within the Create Sequence +Request message of the request path. If you provide this and if the Sandesha2 +server accepts the offered sequence ID it can refrain from doing the Create +Sequence message exchange in the response path. To do this, add the following +to the client code.</p> +<pre>clientOptions.setProperty(SandeshaClientConstants.OFFERED_SEQUENCE_ID,<new uuid>);</pre> +<a name="cras"></a> +<h3>Creating a Sequence Without Sending any Messages</h3> + +<p>Sometimes you may need Sandesha2 client to start a sequence with a server +without sending any real application messages. When you ask for this, +Sandesha2 will do a Create Sequence message exchange and obtain a new +sequence ID from the server. Later you can send application messages with +this newly created sequence. A boolean parameter in this can also be used to +tell whether to send an offer (Read the previous part on <a +href="#oas">offering sequence IDs</a> to learn more about this) . The line +you have to add to your client code for doing these is as follows.</p> +<pre>SandeshaClient.createSequence (ServiceClient serviceClient, booleanoffer);</pre> + +<p>There is another method which takes a third parameter, which is the +Sequence Key (Read the previous part on Sequence Keys to learn more about +this). So with this you can create two or more sequences which can be +identified from different Sequence Keys.</p> +<pre>SandeshaClient.createSequnce (ServiceClient serviceClient, boolean offer, +String sequenceKey);</pre> +<a name="sar"></a> + +<h3>Sending Acknowledgement Requests from the Client Code</h3> + +<p>You can ask the Sandesha2 to get an acknowledgement from a server with +which it is maintaining a sequence. This may be useful in a case where your +<a href="#sequencereport">SequenceReports</a> indicate that some of the +messages you sent have not been acknowledged and when you want to verify +that. You can do this by adding following line to the client +code.</p> +<pre>SandeshaClient.sendAckRequest (ServiceClient serviceClient);</pre> + +<p>You can use following method to send an acknowledgement request to a +specific sequence identified by the Sequence Key.</p> +<pre>SandeshaClient.sendAckRequest (ServiceClient serviceClient, String sequenceKey);</pre> +<a name="sts"></a> + +<h3>Selecting the Specification Version Which you Want to Work in</h3> + +<p>As it was explained earlier Sandesha2 supports two WSRM specifications. The +default is the submitted WSRM specification. But if you want to change this +and work in the new OASIS WSRM specification, set the following property in +the Options object.</p> +<pre>clientOptions.setProperty(SandeshaClient.RM_SPEC_VERSION,Sandesha2Constants.SPEC_VERSIONS.v1_1);</pre> + +<p>To go back to the WSRM submitted specification set the property as +follows.</p> +<pre>clientOptions.setProperty(SandeshaClient.RM_SPEC_VERSION,Sandesha2Constants.SPEC_VERSIONS.v1_0);</pre> +<a name="tas"></a> + +<h3>Terminating a Sequence from the Client Code</h3> + +<p>You can terminate an on going sequence at any time by adding the line +given in this section to your client code. Remember that if you terminate a +sequence some of your messages may not get delivered to the service. This is +the recommended way for old WSRM submitted specification (the default). See +the section '<a href="#smo">Sequence Management of Sandesha2</a>' for more +details.</p> +<pre>SandeshaClient.terminateSequence (ServiceClient serviceClient);</pre> + +<p>To terminate a specific sequence use following.</p> +<pre>SandeshaClient.terminateSequence (ServiceClient serviceClient, String sequenceKey);</pre> +<a name="clas"></a> +<h3>Closing a Sequence from the Client Code</h3> + +<p>You can close an ongoing sequence at any time by adding the line given in +this section to your client code. Sequence close feature is only available +for new WSRM specification being developed under OASIS. Remember that if you +do not close elegantly, some of your messages may not get delivered to the +service. Again, see the section on <a href="#smo">Sequence Management of +Sandesha2</a> for more details. You can issue following command from your +client code to close a sequence.</p> +<pre>SandeshaClient.closeSequence (ServiceClient serviceClient);</pre> + +<p>To close a specific sequence use following.</p> +<pre>SandeshaClient.closeSequence (ServiceClient serviceClient, String sequenceKey);</pre> +<a name="btc"></a> + +<h3>Blocking the Client Code until a Sequence is Complete</h3> + +<p>After your client code delivered some messages to the RM layer, you may +have to wait for some time until the RM layer does its work. The time you +have to block depends on your system performance and network latencies. It +may be easier to ask the RM layer to block until its work is done by issuing +one of the following commands in your client code.</p> +<pre>SandeshaClient.waitUntilSequenceCompleted (ServiceClient serviceClient); + +SandeshaClient.waitUntilSequenceCompleted (ServiceClient serviceClient, String sequenceKey);</pre> + +<p>You can also give the maximum number of seconds the RM Layer should block. +The blocking will stop at the end of this maximum time even if the sequence +is not terminated or not timed out. But note that internally RM is still +working. So even though the blocking stops, RM layer will continue its work +until you exit the program.</p> +<pre>SandeshaClient.waitUntilSequenceCompleted (ServiceClient serviceClient, long maxWaitingTime); + +SandeshaClient.waitUntilSequenceCompleted (ServiceClient serviceClient, long maxWaitingTime, String sequenceKey);</pre> +<a name="smo"></a> + +<h2>Sequence Management of Sandesha2</h2> + +<p>This section will explain you about the sequence managing method of +Sandesha2. This is basically about four things, each explained in following +sub topics.</p> +<a name="san"></a> + +<h3>Starting a New Sequence</h3> + +<p>Sandesha client gets two properties given by the client to decide the +sequence in which it should send a particular application message. First one +is the address of the WS-Addressing To endpoint reference. The second is a +special constant given by the client called Sequence Key which is set as a +property in the Options object as I explained before. Sandesha2 client +generates a value called Internal Sequence ID by combining these two values. +All messages having the same Internal Sequence ID will be sent in a single +sequence, until that particular sequence is terminated.</p> + +<p>Sequences that carry messages from the client to a server are called +request sequences and ones that carry messages from the server to the client +are called response sequences. Sandesha2 always keep a single response +sequence corresponding to a particular request sequence.</p> +<a name="tas"></a> + +<h3>Terminating a Sequence</h3> + +<p>There are currently two methods to terminate a particular sequence from +the Client API. The first method is to <a href="#lastmessage">set the Last Message property</a> as it was +explained earlier. After all the messages up to +the last message get delivered reliably Sandesha2 will terminate that +sequence. Remember that if you are working on the Submitted WSRM +specification (the default), this is the only method you can use.</p> + +<p>If you are working on the new WSRM specification (see previous section on +<a href="#sts">Selecting the Specification Version</a> if you want to know +how to set this), these is an alternate method you can use to terminate a +sequence. You can keep invoking the ServiceClient to send messages, without +setting a Last Message property. After you finish your work call following +function to terminate the sequence.</p> +<pre>SandeshaClient.terminateSequence (ServiceClient);</pre> + +<p>You can use the function below to terminate a sequence identified by a +particular Sequence Key.</p> +<pre>SandeshaClient.terminateSequence (ServiceClient, SequenceKey);</pre> + +<p>When a request sequence is terminated, Sandesha2 will wait till all the +response messages are reliably delivered to the client and after which will +terminate the response sequence as well.</p> +<a name="cas"></a> + +<h3>Closing a Sequence</h3> + +<p>New WSRM specification being developed under OASIS introduces a new +feature called closing a sequence. When a sequence is closed the server will +not except new application messages, but will accept RM control messages like +acknowledgement requests. If you are writing your code for this specification +you can use following functions to close the current sequence.</p> +<pre>SandeshaClient.closeSequence (ServiceClient);</pre> + +<p>You can use the function below to close a sequence identified by a +particular Sequence Key.</p> +<pre>SandeshaClient.terminateSequence (ServiceClient,, SequenceKey);</pre> +<a name="toa"></a> + +<h3>Timing Out a Sequence</h3> + +<p>Depending on its policy configurations Sandesha2 may time out certain +sequences. When a sequence is timed out, it is considered finalized and +cannot be used any more. There are basically two ways a sequence can time +out, and both can be configured using policies. See '<a +href="#inactivitytimeout">InactivityTimeout</a>' and '<a +href="#maximumretransmissioncount">MaximumRetransmissionCount</a>' parts of +the '<a href="#cs">Configuring Sandesha2</a>' sub topic for more details.</p> +<a name="wws"></a> + +<h2>Working with Sandesha Reports</h2> + +<p>Sandesha introduces a feature called Sandesha Reports with which you can +get status information about the sequences managed by Sandesha2. There are +basically two kinds of reports, each explained in following subtopics.</p> +<a name="sandeshareport"></a> + +<h3>SandeshaReport</h3> + +<p>This gives information on all the incoming and outgoing sequences +Sandesha2 system is managing. When we consider a particular endpoint, an +incoming sequence is a sequence to which that endpoint is working as a +RM-Destination (RMD). An outgoing sequence is a sequence to which this +endpoint works as a RM-Source (RMS).</p> + +<p><em><strong>A SandeshaReport include following +information:</strong></em></p> +<ul> + <li>Sequence IDs of all the outgoing sequences.</li> + <li>Number of completed messages of each outgoing sequences.</li> + <li>Sequence IDs of all the incoming sequences.</li> + <li>No of completed messages of each incoming sequence.</li> +</ul> + +<p>To get a SandeshaReport at any time, invoke following method from your +client code.</p> +<pre>SandeshaClient.getSandeshaReport (ConfigurationContext c);</pre> +<a name="sequencereport"></a> +<h3>SequenceReport</h3> + +<p>A SequenceReport gives information on a specific sequences that a Sandesha +system is working on. This can be an incoming sequence or an outgoing +sequence.</p> + +<p><em><strong>A SequenceReport will give following +information:</strong></em></p> +<ol> + <li>Status of the sequence which can be one of the following. + <ul> + <li>INITIAL - The sequence has not been established yet.</li> + <li>ESTABLISHED - Create Sequence / Create Sequence Response message + exchange has been done.</li> + <li>TERMINATED - The sequence has been terminated.</li> + <li>TIMEDOUT - The sequence has timed out.</li> + <li>UNKNOWN - The status cannot be determined.</li> + </ul> + </li> + <li>Sequence Direction + <ul> + <li>OUT - Outgoing sequence</li> + <li>IN - Incoming sequence</li> + </ul> + </li> + <li>Sequence ID of the sequence</li> + <li>Internal sequence ID of the sequence.</li> + <li>Number of completed messages of the sequence.</li> +</ol> + +<p>A messages is considered as <strong>completed</strong> when a RMS has +successfully sent the message to the RMD and received an acknowledgement.</p> + +<p>To get an incoming sequence report, you have to issue following command +from your client code.</p> +<pre>SandeshaClient.getIncomingSequenceReports (ConfigurationContext configCtx);</pre> + +<p>To get an outgoing Sequence Report you can invoke any of the following +functions.</p> +<pre>SandeshaClient.getOutgoingSequenceReport (ServiceClient serviceClient); +SandeshaClient.getOutgoingSequenceReport (String to,String sequenceKey,ConfigurationContext configurationContext); +SandeshaClient.getOutgoingSequenceReport (String internalSequenceID,ConfigurationContext configurationContext);</pre> +<a name="slf"></a> + +<h2>Sandesha Listener Feature</h2> + +<p>You can use this new feature to register a listener class in Sandesha2 and +get notified when specific event happens in the system. The basic interface +is given below.</p> +<pre>public interface SandeshaListener { + public void onError(AxisFault fault); + public void onTimeOut(SequenceReport report); +}</pre> + +<p>You can implement this class and set an object of that type as a property +in the Options object in your client code. An example is given below.</p> +<pre>options.setProperty (SandeshaClientConstants.SANDESHA_LISTENER, new SandeshaListnerImpl ());</pre> + +<p>Currently SandeshaListener defines the following two methods- onError +& onTimedOut.</p> +<a name="onerror"></a> +<h3>onError</h3> + +<p>This will be invoked if Sandesha2 receives a fault SOAP message for one of +the protocol messages it sent. The parameter will be an AxisFault +representing that fault message. Remember that this will not be invoked for +faults that occur due to application messages or any other messages that do +not get originated from Sandesha2. They will not be considered by the +Sandesha2 system as valid application messages.</p> +<a name="ontimeout"></a> +<h3>onTimeOut</h3> + +<p>As mentioned in the earlier section <a href="#smo">Sequence Management of +Sanesha2</a>, there is a possibility of an inactive sequence timing out. When +a specific sequence times out, this method of the SandeshaListener will be +invoked giving a report of that sequence as a parameter.</p> +<a name="dao"></a> +<h2>Delivery Assurances of Sandesha2</h2> + +<p>As it was mentioned in the <a href="architectureGuide.html" target="_blank">Architecture +Guide</a>, Sandesha2 provide an in-order exactly-once delivery assurance. +<strong>In-order</strong> means that Sandesha2 will guarantee delivering of +the messages to the Web service in the order of their message numbers. If you +use a Sandesha2 client this will be the order you called the invocation +methods of your service client. <strong>Exactly-once</strong> delivery +assurance means that Sandesha2 will make sure that the service will be +invoked only once for each message. As it was mentioned earlier Sandesha2 +retransmits messages to obtain reliability. Due to the exactly-once delivery +assurance you can be sure that your service gets invoked only once.</p> + +<p>If you require the performance to be maximized and if you do not want +ordering, you can configure Sandesha2 to invoke messages in the order they +arrive. Read 'Configuring Sandesha2' section below to learn how to do +this.</p> +<a name="cs"></a> +<h2>Configuring Sandesha2</h2> + +<p>Sandesha2 provides a set of configurations which you can use to customize +its execution behavior. All these configurations are available in a WS-Policy +format. These policies can be in the module.xml file of the Sandesha module +or in the services.xml file of a service on which Sandesha2 module has been +engaged. Most of the policies in the module.xml can be overridden by setting +different values in a services.xml. But some policies cannot be overridden +and must be set correctly in the module.xml file.</p> + +<p>You will find each Sandesha2 policy and the way an alteration of it can +effect Sandesha2. Make sure that you set these values carefully. Setting +incompatible types or values may cause Sandesha system to malfunction. +Normally if Sandesha2 can detect that the value you have set is incompatible, +it will set a default value which is mentioned in the SandeshaConstants +class.</p> +<a name="acknowledgementinterval"></a> +<h3>AcknowledgementInterval</h3> + +<p>When a RMD receives an application message and when it has to send +acknowledgements to an endpoint (other than the anonymous URL), it will not +send this message immediately but will wait for some time to see whether +there are any other messages (for example application response messages) +going towards the destination of the acknowledgement message. If it finds +any, the acknowledgement message is piggybacked in this second message and +both are sent together. If the RMD does not find any messages that go towards +the destination of the acknowledgement within a specific time interval, the +acknowledgement is sent as a stand alone message. This time interval is +called the <strong>acknowledgement interval</strong> and can be configured in +Sandesha2 policies. The measurement unit is in milliseconds.</p> +<a name="retransmissioninterval"></a> +<h3>RetransmissionInterval</h3> + +<p>As it was mentioned earlier some messages in RM should be retransmitted +until a proper response or acknowledgement is returned. After sending a +message once, the RMS will wait for some time before sending it for the +second time. This waiting time between the first and second retransmission +attempts is given by this policy. If the policy given later called the +ExponentialBackoff is set to false the time gap between all the +retransmissions attempts will have the same value, which is the +RetransmissionInterval. Measurement unit is in milliseconds.</p> +<a name="exponentialbackoff"></a> + +<h3>ExponentialBackoff</h3> + +<p>Value of this can either be 'true' or 'false'. This measure is used to +adjust the retransmission attempts so that an RMD does not get flooded with a +large number of retransmitted messages. If this is 'true', a time gap between +two retransmissions will be twice as the time gap between previous two +retransmissions. For example, if the time gap between the fourth and fifth +retransmission attempts is twenty seconds the time gap between the fifth and +sixth attempts will be forty seconds. If this property is set to 'false', all +retransmissions will have the same value, which is given by the +'RetransmissionInterval' property.</p> +<a name="maximumretransmissioncount"></a> +<h3>MaximumRetransmissionCount</h3> + +<p>This gives the maximum number of times a message has to be retransmitted. +When a specific message gets retransmitted a maximum number of times, and is +still not sent correctly to the RMD, it will not be sent again and the +request will be marked as Timed Out. When a sequence is timed out, it cannot +be used any more. If the value of this property is '-1' there is no limit in +the number of retransmission attempts.</p> +<a name="inactivitytimeout"></a> +<h3>InactivityTimeout</h3> + +<p>A Sandesha2 RMS always keeps track of the last time a particular RMD +responded to a request by it. If the RMD does not response within the time +limit given by the time interval given by this measure, the RMS will give up +attempting and will mark the sequence as Timed Out. After timing out the +particular sequence, it cannot be used any more. If the value of this is -1, +there is not inactivity timeout limit The measure of this is given by the +property 'InactivityTimeoutMeasure'.</p> +<a name="inactivitytimeoutmeasure"></a> +<h3>InactivityTimeoutMeasure</h3> +<p>This gives the measure of the property 'InactivityTimeout'. The value of +this can be seconds, minutes, hours or days. If you give a value that cannot +be interpreted the default will be used.</p> +<a name="invokeinorder"></a> +<h3>InvokeInOrder</h3> +<p>As it was mentioned earlier, Sandesha2 implement the in-order invoking +delivery assurance. This property can be used to turn this on or off. The +value of this has to be 'true' if in-order invoking has to be enabled. It has +to be false if in-order invoking has to be disabled. Please remember that +this is a non-overridable property. I.e. value you set in the module.xml is +the one that is used for all the services and will not be overridden for a +particular service by setting a different value there.</p> +<a name="storagemanager"></a> +<h3>StorageManager</h3> + +<p>This gives the storage manager implementation class used by Sandesha2. You +have to mention the full qualified class name here. Please read the Sandesha2 +<a href="architectureGuide.html">Architecture Guide</a> for more details on +creating your own storage manager. This is also a property that cannot be +overridden, i.e., value you set in the module.xml is the one that is used for +all the services and will not be overridden for a particular service by +setting a different value there.</p> +<a name="messagetypestodrop"></a> + +<h3>MessageTypesToDrop</h3> + +<p>This is a property that may not be very useful to an end user, but may be +useful for some debug purposes. As it was mentioned earlier Sandesha2 gives a +Message Type to each message it sends. For example, Create Sequence messages +will have the type 1 and Acknowledgement messages will have the type 4. You +can add a comma separated list of integers in the property telling Sandesha2 +not to send messages of those types.</p> +</body> +</html>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
