<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>WSO2 Oxygen Tank</title>
  <subtitle>Developer Portal for Open Source SOA Web Services and Middleware</subtitle>
  <link rel="alternate" type="text/html" href="http://dist.wso2.org"/>
  <link rel="self" type="application/atom+xml" href="http://dist.wso2.org/atom/feed"/>
  <id>http://dist.wso2.org/atom/feed</id>
  <updated>2009-01-06T11:49:32+00:00</updated>
  <entry>
    <title>Introduction to WSO2 Carbon Clustering</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/articles/introduction-wso2-carbon-clustering" />
    <id>http://dist.wso2.org/library/articles/introduction-wso2-carbon-clustering</id>
    <published>2009-01-05T09:45:00+00:00</published>
    <updated>2009-01-06T07:22:12+00:00</updated>
    <author>
      <name>afkham_azeez</name>
    </author>
    <category term="Articles" />
    <category term="Intermediate" />
    <category term="Architecture" />
    <category term="Axis2" />
    <category term="Carbon" />
    <category term="carbon" />
    <category term="clustering" />
    <category term="Java" />
    <summary type="html"><![CDATA[<p>In this article, <strong>Afkham Azeez</strong> - Architect and Product Manager for WSO2 WSAS, explains some of the core concepts associated with <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a> clustering.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>In this article, <strong>Afkham Azeez</strong> - Architect and Product Manager for WSO2 WSAS, explains some of the core concepts associated with <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a> clustering.</p>
<p>Note: In a future article titled 'WSO2 Carbon Cluster Configuration Language'[1], he hopes to dive into specific details of the WSO2 Carbon clustering configuration language.</p>
<h3>Abstract</h3>
<p>Clustering for high availability and scalability is one of the main requirements of any enterprise deployment. This is also true for <a href="http://wso2.com">WSO2</a>'s open source SOA middleware products. However, configuring a cluster can be tricky. <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a>, which is the name of the base framework and the architecture of the newer generation of WSO2's open source SOA middleware products, has extensive support for clustering. WSO2 Carbon inherits clustering capabilities from <a href="http://ws.apache.org/axis2/">Apache Axis2</a>. State replication amongst members in the same group as well as cluster management are available in WSO2 Carbon.</p>
<h2>Table of Contents</h2>
<ul>
<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#org.apache.axis2.clustering.ClusteringAgent">org.apache.axis2.clustering.ClusteringAgent</a></li>
<li><a href="#org.apache.axis2.clustering.state.StateManager">org.apache.axis2.clustering.state.StateManager</a></li>
<li><a href="#org.apache.axis2.clustering.management.NodeManager">org.apache.axis2.clustering.management.NodeManager</a></li>
<li><a href="#org.apache.axis2.clustering.management.GroupManagementAgent">org.apache.axis2.clustering.management.GroupManagementAgent</a></li>
<li><a href="#Membership%20Schemes">Membership Schemes</a>
<ul>
<li><a href="#Static%20Membership">Static Membership</a></li>
<li><a href="#Dynamic%20Membership">Dynamic Membership</a></li>
<li><a href="#Hybrid%20Membership">Hybrid Membership</a></li>
</ul>
</li>
<li><a href="#Conclusion">Conclusion</a></li>
<li><a href="#References">References</a></li>
</ul>
</ul>
<h2 id="Introduction">Introduction</h2>
<p>The Apache Axis2[2] Web services engine is the base of WSO2 Carbon[3] and WSO2 Carbon is the base of the newer generation of Java middleware products from WSO2. WSO2 Carbon inherits clustering features from Apache Axis2. Axis2 clustering is designed in a way that all functionality is abstracted out by a set of interfaces. By implementing these interfaces and providing the implementation classes in the clustering configuration section, any clustering implementation can be plugged in. One may require to use a group management framework of his choice, in which case he can implement these interfaces and then plug them using the clustering configuration section in the axis2.xml file. We will be taking a look at the usages of these interfaces later. The default clustering implementation in Axis2 is based on Apache Tribes[4], the popular group management framework used by Apache Tomcat[5].</p>
<p>The Axis2 clustering APIs address 2 concerns; state replication and management. State replication refers to the synchronizing of states related to different members in a cluster group. Management can again be divided into two aspects; Group Management and Node Management.</p>
<p>The 4 interfaces that may be implemented by an Axis2 clustering implementation are:</p>
<ul>
<li>org.apache.axis2.clustering.ClusteringAgent</li>
<li>org.apache.axis2.clustering.state.StateManager</li>
<li>org.apache.axis2.clustering.management.NodeManager</li>
<li>org.apache.axis2.clustering.management.GroupManagementAgent</li>
</ul>
<h2 id="org.apache.axis2.clustering.ClusteringAgent">org.apache.axis2.clustering.ClusteringAgent</h2>
<p>This is the main interface in the Axis2 clustering implementation. In order to plug-in a new clustering implementation, this interface has to be implemented.</p>
<p>The ClusteringAgent is responsible for initializing all clustering related functionalities of a Carbon member or node. Generally, the initilization of a node in a cluster is handled here. It is also responsible for getting this node to join the cluster. This node should not process any Web services requests until it successfully joins the cluster. Generally, this node will also need to obtain state information and/or configuration information from a neighboring node. State information needs to be obtained as prior to joining the group this new member needs to be in sync with the other members with respect to the state. It is also possible that configuration changes have taken place. For example, new service deployments or service undeployments may have taken place after nodes in a group were initialized. Hence, it is essential that all configuration changes are kept in sync across a group. This interface is also responsible for properly initializing the org.apache.axis2.clustering.state.StateManager, org.apache.axis2.clustering.management.NodeManager and org.apache.axis2.clustering.management.GroupManagementAgent implementations. In the case of a static membership scheme, members are read from the axis2.xml file and added to the ClusteringAgent. Later, we will take a look at different membership schemes supported by Axis2.</p>
<p>In the axis2.xml, the instance of this interface is specified using the &quot;clustering&quot; class attribute.</p>
<p>There can also be several &quot;parameter&quot; elements, which are children of the &quot;clustering&quot; element in the axis2.xml file. Generally, these parameters will be specific to the ClusteringAgent implementation. In the default Apache Tribes based implementation, there are several parameters that are required to initialize the Tribes Channel properly.</p>
<h2 id="org.apache.axis2.clustering.state.StateManager">org.apache.axis2.clustering.state.StateManager</h2>
<p>This interface is responsible for handling state replication. The word 'state' here means the serializable values stored in the Axis2 context hierarchy which need to be kept in sync across all the members of a cluster group. Property changes (state changes) in the Axis2 context hierarchy in the node which runs this StateManager will be propagated to all other nodes in its group. In the Tribes based clustering implementation, we have only enabled replication of serializable objects stored in the Apache Axis2 ConfigurationContext, ServiceGroupContext and ServiceContext. Hence, if a user requires state replication, it is this user's responsibility to store these values in the proper Axis2 contexts. Generally, Web services authors do not have to handle state replication, as it is handled by the clustering implementation just before request completion. This is done at the Axis2 MessageReceivers. However, if the developer writes his own MessageReceiver, he will need to call the org.apache.axis2.clustering.state.Replicator#replicate() method. Also note that at any point org.apache.axis2.clustering.state.Replicator#replicate() can be called, if the developer wishes to force state replication.</p>
<p>It is not mandatory to have a StateManager in a node. If we are not interested in high availability, we may disable state replication. In such a scenario, in general, the purpose of a clustered deployment is to achieve scalability. In addition, one may also enable clustering without state replication simply to utilize the group communication capabilities of the underlying Group Communication Framework (GCF). In such a case, the purpose of a clustered deployment may also be management of the cluster using&nbsp; the underlying GCF. WSO2 Carbon provides such a component which allows cluster management.</p>
<p>The implementation of this interface is set by&nbsp; reading the&nbsp; &quot;stateManager&quot; element in the axis2.xml clustering section.</p>
<h2 id="org.apache.axis2.clustering.management.NodeManager">org.apache.axis2.clustering.management.NodeManager</h2>
<p>This interface is responsible for handling management of a particular member.&nbsp; It is not mandatory to have a NodeManager in a node. Node management is generally used for deploying or undeploying services across a cluster group. However, this interface is not used at the moment in Carbon. The implementation of this interface is set by reading the&nbsp; &quot;nodeManager&quot; element in the axis2.xml.</p>
<h2 id="org.apache.axis2.clustering.management.GroupManagementAgent">org.apache.axis2.clustering.management.GroupManagementAgent</h2>
<p>This is the interface through which group management events are notified and messages are sent to members in a particular group. This will only be used when a member is running in group management mode. In group management mode, a member is special and belongs to all groups which it is managing. Hence, any membership changes in the groups it manages will be notified by the underlying group management framework to the group management agent. A group management agent should be specified for each group that has to be managed by the member. In WSO2 Carbon cluster management, the cluster manager node needs to define group management agents for each group.</p>
<p>The WSO2 Enterprise Service Bus (ESB) is capable of dynamic load balancing. Here, new members can join and leave the application group, and this will be reflected in the membership aware dynamic load balancer. The clustering configuration for the dynamic load balancer needs to be configured with group management to allow group membership discovery.</p>
<h2 id="Membership Schemes">Membership Schemes</h2>
<p>The Axis2 and WSO2 Carbon clustering implementations support several membership schemes.</p>
<h3 id="Static Membership">Static Membership</h3>
<p>In this scheme, only a defined set of members can be in a group. The Group Membership Service(GMS) will detect members joining or leaving the group. External members cannot join the group. Each node may obtain group member details from a central repository or configuration file.</p>
<h3 id="Dynamic Membership">Dynamic Membership</h3>
<p>In this scheme, membership is not predefined. Members can join a group by specifying the appropriate group name, and also leave the group. The Group Management Service (GMS) will detect new members joining or leaving. Group membership information may be obtained from the GMS.</p>
<h3 id="Hybrid Membership">Hybrid Membership</h3>
<p>This scheme is also called Well-Known Addressed (WKA) based membership. In this scheme, there are a set of well-known members. We can consider these members as belonging to a static group. External members can join this group by notifying one of the well known members. These external members can then get the current group membership from this well-known member. When new members join the group, well-known members will notify all other members. When members leave the group, the GMS can detect this event.</p>
<h2 id="Conclusion">Conclusion</h2>
<p>In this article, we had a detailed look at some of the core clustering concepts in WSO2 Carbon and Apache Axis2. These concepts will be essential when it comes to understanding different cluster configuration options, as well as developing different clustering implementations for Apache Axis2 and WSO2 Carbon. In the next article in this series, <a href="http://wso2.org/library/articles/wso2-carbon-cluster-configuration-language">WSO2 Carbon Cluster Configuration Language</a>, we will see how the concepts we discussed in this article can be realized.</p>
<h2 id="References">References</h2>
<ol>
<li>WSO2 Carbon Cluster Configuration Language, http://wso2.org/library/articles/wso2-carbon-cluster-configuration-language</a></li>
<li>Apache Axis2, <a href="http://ws.apache.org/axis2/">http://ws.apache.org/axis2/</a></li>
<li>WSO2 Carbon, <a href="https://wso2.org/projects/carbon/">https://wso2.org/projects/carbon/</a></li>
<li>Apache Tribes, <a href="http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html">http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html</a></li>
<li>Apache Tomcat, <a href="http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html">http://tomcat.apache.org/</a></li>
</ol>
<h2 id="About the Author">About the Author</h2>
<p>Afkham Azeez is the Architect and Product Manager for WSO2 WSAS. He also designed and developed the Axis2 clustering implementation. Currently, he is working on making Apache Axis2 Web services and WSO2 products automatically scale on cloud infrastructures.</p>
    ]]></content>
  </entry>
  <entry>
    <title>Invoking Web Services from a Mashup</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/tutorials/invoking-web-services-mashup" />
    <id>http://dist.wso2.org/library/tutorials/invoking-web-services-mashup</id>
    <published>2009-01-01T04:21:02+00:00</published>
    <updated>2009-01-05T14:55:45+00:00</updated>
    <author>
      <name>keith</name>
    </author>
    <category term="Tutorials" />
    <category term="Introductory" />
    <category term="mashup" />
    <category term="Mashup Server" />
    <category term="webservices" />
    <category term="WSO2 Mashup Server" />
    <summary type="html"><![CDATA[<p>In this tutorial by <strong>Keith Chapman</strong>, he takes you through the mechanisms supported by the <a href="http://wso2.org/projects/mashup">WSO2 Mashup Server</a> for invoking Web services.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>In this tutorial by <strong>Keith Chapman</strong>, he takes you through the mechanisms supported by the <a href="http://wso2.org/projects/mashup">WSO2 Mashup Server</a> for invoking Web services.</p>
<ul>
<li><a href="#%3Cbr%3E">Introduction</a></li>
<li><a href="#Invoking%20Web%20Services%20from%20your%20mashup">Invoking Web Services from your mashup</a>
<ul>
<li><a href="#Invoking%20Services%20using%20a%20generated%20stub">Invoking Services using a generated stub</a>
<ul>
<li><a href="#Invoking%20a%20service%20in%20a%20synchronous%20manner">Invoking a service in a synchronous manner</a></li>
<li><a href="#Invoking%20a%20service%20in%20a%20asynchronous%20manner">Invoking a service in a asynchronous manner</a></li>
<li><a href="#%3Cspan%3EInvoking%20a%20service%20secured%20using%20Username%20Token%20authentication%3C/span%3E">Invoking a service secured using Username Token authentication</a></li>
</ul>
</li>
<li><a href="#%3Cspan%3EInvoking%20services%20using%20the%20WSRequest%20Host%20Object%3C/span%3E">Invoking services using the WSRequest Host Object</a>
<ul>
<li><a href="#%3Cspan%3EInvoking%20a%20service%20is%20a%20synchronous%20manner%3C/span%3E">Invoking a service is a synchronous manner</a></li>
<li><a href="#%3Cspan%3EInvoking%20a%20service%20is%20a%20asynchronous%20manner%3C/span%3E">Invoking a service is a asynchronous manner</a></li>
<li><a href="#%3Cspan%3EInvoking%20a%20service%20secured%20using%20Username%20Token%20authentication%3C/span%3E">Invoking a service secured using Username Token authentication</a></li>
</ul>
</li>
<li><a href="#%3Cspan%3EInvoking%20services%20using%20the%20dynamic%20version%20of%20the%20WSRequest%20Host%20Object%3C/span%3E">Invoking services using the dynamic version of the WSRequest Host Object</a>
<ul>
<li><a href="#%3Cspan%3EInvoking%20a%20service%20is%20a%20synchronous%20manner%3C/span%3E">Invoking a service is a synchronous manner</a></li>
<li><a href="#%3Cspan%3EInvoking%20a%20service%20is%20a%20asynchronous%20manner%3C/span%3E">Invoking a service is a asynchronous manner</a></li>
<li><a href="#%3Cspan%3EInvoking%20a%20secured%20service%3C/span%3E">Invoking a secured service</a>
<ul>
<li><a href="#%3Cspan%3ESetting%20up%20the%20certificates%3C/span%3E">Setting up the certificates</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#Future%20Directions">Future Directions</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
</ul>
<h1 id="&lt;br&gt;">Introduction</h1>
<p>The objective of a mashup is to compose or mash information obtained from several sources. The WSO2 Mashup Server supports several ways and means of getting such information. Invoking external Web services (or mashups deployed on the same server) is a popular mechanism of obtaining such information.</p>
<h1 id="Invoking Web Services from your mashup">Invoking Web services from your mashup</h1>
<p>The mashup server supports three main ways of invoking Web services. They are,</p>
<ul>
<li>Using a generated JavaScript stub</li>
<li>Using the WSRequest Host Object</li>
<li>Using the Dynamic version of the WSRequest Host Object</li>
</ul>
<p>Each of these mechanisms have there pros and cons. The following table summarizers them:</p>
<p>&nbsp;</p>
<table width="90%" align="center" border="1" cellpadding="1" cellspacing="1">
<tr>
<td>Method</td>
<td>Pros</td>
<td>Cons</td>
</tr>
<tr>
<td>Generated Stub</td>
<td>
<p>Ease of use</p>
<p>No need to frame the message manually, the stub takes care of it</p>
<p>Ability to invoke services secured using Username Token (With ease)</p>
<p>No configuration needed (All such configurations are picked off the WSDL)</p>
</td>
<td>
<p>Ease of use depends on the schema of the messages used by the service. If the schemas are complex the stub might not be able to databind them effectively.</p>
<p>Not able to invoke all secured services</p>
<p>The service needs be described using WSDL (Either WSDL 1.1 or WSDL 2.0)</p>
</td>
</tr>
<tr>
<td>WSRequest Host Object</td>
<td>
<p>Offers greater flexibility</p>
<p>Ability to invoke services secured using Username Token</p>
</td>
<td>
<p>Users need to frame the request message manually</p>
<p>All options are needed to be configured manually</p>
</td>
</tr>
<tr>
<td>Dynamic version of the WSRequest Host Object</td>
<td>
<p>Ease of use</p>
<p>Ability to access secured services provided that the WSDL describes such security requirements using WS-Securoty Policy (Even if it employs complex security scenarios)</p>
<p>No configuration needed (All such configurations are picked off the WSDL)</p>
</td>
<td>Not too good when it comes to performance (As the WSDL needs to be parsed in order to configure the WSRequest Host Object)</p>
<p>Users need to frame the request message manually</p>
<p>The service needs to have a WSDL 1.1 description</p>
</td>
</tr>
</table>
<p>There are certain features that are supported by all above methods. Some of them are,</p>
<ul>
<li>Ability to invoke services in both synchronous and asynchronous manner</li>
<li>Ability to invoke services over several transports (Provided that these transports are configured in the Mashup Server)</li>
<li>Ability to invoke both REST and SOAP services</li>
</ul>
<p>Let's now take a deeper look at each of these. We'll also go into examples that demonstrate how these features can be used.</p>
<p>For samples that do not involve security, I will be using the Currency Converter service that is available on webservicex.net. Details of this service can be found at <a href="http://www.webservicex.net/CurrencyConvertor.asmx">http://www.webservicex.net/CurrencyConvertor.asmx.</a> For others that involve security I will be using a couple of demo services that I've put up on <a href="http://mooshup.com">mooshup.com</a> (Which is a community site where users can upload there mashups to. This site is running an instance of the WSO2 Mashup Server).</p>
<h2 id="Invoking Services using a generated stub">Invoking Services using a generated stub</h2>
<p>If you are invoking a service that runs on the WSO2 Mashup Server (local or remote), you should be able to get a stub for that service by visiting its home page. The home page of a mashup lists several versions of stubs that you could use. For the purpose of invoking external services from within a mashup the E4X version of the stub should be used (The DOM version of the stub would not work when used by a mashup, it is to be used in a browser environment). If the service you are trying to invoke resides on the same Mashup Server then it is advisable to use the localhost version of the stub.</p>
<p>If the service been invoked is not running on a WSO2 Mashup Server you may first need to generate a stub for the service. This can be done by using the stub generation tool that ships with the WSO2 Mashup Server (It is available at <a href="http://localhost:7762/stub_gen.jsp">http://localhost:7762/stub_gen.jsp</a>). Please make sure that you use the E4X version of the stub.</p>
<p>When stubs are used to invoke a service, you should save the stub inside the resources folder of your mashup (Even though the Mashup Server allows you to import a stub for a mashup using relative URIs, it is not advisable to do so, as the Mashup Server does not handle inter-service dependencies) and import it from there. Stubs can be imported using the &ldquo;system.include()&rdquo; function. E.g. Assuming the stub was saved in the resources folder as &ldquo;stub.js&rdquo; this could be included as &ldquo;system.include(&ldquo;stub.js&rdquo;);&rdquo;</p>
<p>For more details on how the stubs generated could be used, please refer the &ldquo;Using stubs&rdquo; section of the Mashup Server <a href="https://wso2.org/project/mashup/1.5.1/docs/index.html">documentation</a>.</p>
<p>Now that we've seen how a stub can be generated for a service and imported to a mashup, it is time to see how this stub can be used. For your convenience each stub generated would contain a section at the top (which is commented out) and shows how the stub could be used to invoke the service. Let's get into some code samples now.</p>
<h3 id="Invoking a service in a synchronous manner">Invoking a service in a synchronous manner</h3>
<p>Invoking a service in a synchronous manner using a stub is just a matter of calling a simple JavaScript function passing in the arguments accepted by the service. The stub would take care of creating the payload using the arguments passed into it as well as unwrapping the response for you. The stub will also configure the WSRequest host object with details needed to invoke the service. These details include the service EPR (Endpoint reference), the SOAP action required and so on.</p>
<pre class="prettyprint">
system.include(&quot;currencyConvertorStub.js&quot;); 

convertionRateUsingStub.inputTypes={&quot;fromCurrency&quot; : &quot;string&quot;, &quot;toCurrency&quot; : &quot;string&quot;}; 
convertionRateUsingStub.outputType=&quot;string&quot;; 
function convertionRateUsingStub(fromCurrency, toCurrency){ 
    var rate =  CurrencyConvertor.ConversionRate(fromCurrency, toCurrency); 
    return &quot;The conversion rate is &quot; + rate; 
}
</pre><h3 id="Invoking a service in a asynchronous manner">Invoking a service in a asynchronous manner</h3>
<p>In order to invoke a service in a asynchronous manner using a stub the user needs to set a callback function. The stub uses this as a hint to decide whether the call it makes should be synchronous or asynchronous. Alternatively users could set  a function as the onError property which would be triggered of a fault is received as the response. In my example I define two function &ldquo;success&rdquo; and &ldquo;failure&rdquo; and set them as the callback and onError functions. (I've set the visible property of the &ldquo;success&rdquo; and &ldquo;failure&rdquo; functions to false so that these function would not appear as function of this mashup, they are kept for private use).</p>
<pre class="prettyprint">
convertionRateUsingStubAsync.inputTypes={&quot;fromCurrency&quot; : &quot;string&quot;, &quot;toCurrency&quot; : &quot;string&quot;}; 
convertionRateUsingStubAsync.outputType=&quot;string&quot;; 
function convertionRateUsingStubAsync(fromCurrency, toCurrency){ 
    CurrencyConvertor.ConversionRate.callback = success; 
    CurrencyConvertor.ConversionRate.onError = failure; 
    CurrencyConvertor.ConversionRate(fromCurrency, toCurrency); 
    return &quot;Invoked the ConversionRate operation in a async manner&quot;; 
} 

success.visible=false; 
function success(ConversionRateResponse) { 
    system.log(&quot;The response of ConversionRate was : &quot; + ConversionRateResponse); 
} 

failure.visible=false; 
function failure(error) { 
    system.log(&quot;Error occured while calling ConversionRate, Reason is : &quot; + error.reason); 
}</pre><p>Note: By default the stub would use the SOAP 1.2 endpoint to invoke the service (If the service does not contain a SOAP 1.2 endpoint if will look for a SOAP 1.1 endpoint. If that fails it uses the first endpoint defined in the WSDL). If users wish to change the endpoint, they could change it by setting the &ldquo;endpoint&rdquo; property of the service.</p>
<p>Users could also change the endpoint address of a specific endpoint by using the setAddress function in the stub. The syntax is &ldquo;{service}.setAddress(endpoint, url)&rdquo;.</p>
<p>&nbsp;</p>
<h3 id="&lt;span&gt;Invoking a service secured using Username Token authentication&lt;/span&gt;">Invoking a service secured using Username Token authentication</h3>
<p>A cool feature of the JavaScript stubs generated by the Mashup Server is that it has the ability to invoke services secured using Username Token authentication. To invoke such a service users can set the Username and password using a couple of JavaScript properties on the stub. Namely &ldquo;{service}.username&rdquo; and &ldquo;{service}.password&rdquo;. For this example, let's use the <a href="http://mooshup.com/mashup.jsp?author=keith&amp;mashup=usernameTokenService">usernameTokenService</a> service which is deployed on <a href="http://mooshup.com">mooshup.com.</a> It has been secured such that any registered user on <a href="http://mooshup.com">mooshup.com</a> can access this service. </p>
<p>Save the stub for the usernameTokenService (<a href="http://mooshup.com/services/keith/usernameTokenService?stub&amp;lang=e4x&amp;content-type=text/plain">http://mooshup.com/services/keith/usernameTokenService?stub&amp;lang=e4x&amp;content-type=text/plain</a>) in the resources folder of your mashup.</p>
<pre class="prettyprint">
system.include(&quot;usernameTokenServiceStub.js&quot;);

invokeSecuredService.inputTypes={&quot;firstParam&quot; : &quot;string&quot; , &quot;secondParam&quot; : &quot;string&quot;};
invokeSecuredService.outputType=&quot;string&quot;;
function invokeSecuredService(firstParam, secondParam) {
    usernameTokenService.username = &quot;yourUsername&quot;;
    usernameTokenService.password = &quot;yourPassword&quot;;
    return usernameTokenService.demo(firstParam, secondParam);
}</pre><p>Note : Please replace &ldquo;yourUsername&rdquo; and &ldquo;yourPassword&rdquo; with your credentials before running this example.</p>
<p>&nbsp;</p>
<h2 id="&lt;span&gt;Invoking services using the WSRequest Host Object&lt;/span&gt;">Invoking services using the WSRequest Host Object</h2>
<p>When using the WSRequest Host Object to invoke a service the user is expected to provide all details needed to invoke the service. The user also has to provide the payload needed to invoke the service. This requires the user to have some knowledge about the service (In order to know what the payload should look like, this could be inferred by looking at the WSDL of the service).</p>
<p>&nbsp;</p>
<h3 id="&lt;span&gt;Invoking a service is a synchronous manner&lt;/span&gt;">Invoking a service is a synchronous manner</h3>
<p>Invoking a service in a synchronous manner is straightforward and can be done in the following manner:</p>
<pre class="prettyprint">
convertionRateUsingWSRequest.inputTypes={&quot;fromCurrency&quot; : &quot;string&quot;, &quot;toCurrency&quot; : &quot;string&quot;}; 
convertionRateUsingWSRequest.outputType=&quot;string&quot;; 
function convertionRateUsingWSRequest(fromCurrency, toCurrency){ 
    var request = new WSRequest();
    var options = new Array();
    options.useSOAP = 1.1;
    options.useWSA = false;
    options.action = &quot;http://www.webserviceX.NET/ConversionRate&quot;;
    var payload = {fromCurrency}{toCurrency};
    var result;
    try {
        request.open(options,&quot;http://www.webservicex.net/CurrencyConvertor.asmx&quot;, false);
        request.send(payload);
        var response = request.responseE4X;
        var ns = new Namespace('http://www.webserviceX.NET/');
        result = response.ns::[&quot;ConversionRateResult&quot;].toString();
    } catch (e) {
        system.log(e.toString(),&quot;error&quot;);
        return result = e.toString(); 
    }
    return result;
}
</pre><h3 id="&lt;span&gt;Invoking a service is a asynchronous manner&lt;/span&gt;">Invoking a service is a asynchronous manner</h3>
<p>When a service is invoked in a asynchronous manner, the user needs to set a function that will be called when the state of the invocation changes. These states are identical to the readyStates found when using the XMLHttpRequest object in a browser enviorenment. readyState 4 states that the invocation was completed succesfully. </p>
<pre class="prettyprint">
convertionRateUsingWSRequestAsync.inputTypes={&quot;fromCurrency&quot; : &quot;string&quot;, &quot;toCurrency&quot; : &quot;string&quot;}; 
convertionRateUsingWSRequestAsync.outputType=&quot;string&quot;; 
function convertionRateUsingWSRequestAsync(fromCurrency, toCurrency){ 
    var request = new WSRequest();
    var options = new Array();
    options.useSOAP = 1.1;
    options.useWSA = false;
    options.action = &quot;http://www.webserviceX.NET/ConversionRate&quot;;
    request.onreadystatechange = function() {
         handleResponse(request);
    };
    var payload = {fromCurrency}{toCurrency};
    var result;
    try {
        request.open(options,&quot;http://www.webservicex.net/CurrencyConvertor.asmx&quot;, true);
        request.send(payload); 
        result = &quot;Invoked the CurrencyConvertor service&quot;;        
    } catch (e) {
        system.log(e.toString(),&quot;error&quot;);
        return result = e.toString(); 
    }
    return result;
}

handleResponse.visible=false;
function handleResponse(request){
    if (request.readyState == 4) {
        var response = request.responseE4X;
        var ns = new Namespace('http://www.webserviceX.NET/');
        var result = response.ns::[&quot;ConversionRateResult&quot;].toString();
	system.log(result);
    }
}
</pre><h3 id="&lt;span&gt;Invoking a service secured using Username Token authentication&lt;/span&gt;">Invoking a service secured using Username Token authentication</h3>
<p>When invoking a service secured using Username Token authentication, the user needs to set a few properties on the options object. They are the &quot;username&quot; property and the &quot;password&quot; property. The user also needs to set the &quot;useWSS&quot; property to true. This instructs the WSRequest Host object to use the username and password provided as security tokens. If the &quot;useWSS&quot; property is not set to true the username and password provided will be used as credentials for HTTP Basic Authentication.</p>
<pre class="prettyprint">
invokeSecuredService.inputTypes={&quot;firstParam&quot; : &quot;string&quot; , &quot;secondParam&quot; : &quot;string&quot;};
invokeSecuredService.outputType=&quot;string&quot;;
function invokeSecuredService(firstParam, secondParam) {
    var request = new WSRequest();
    var options = new Array();
    options.useSOAP = 1.2;
    options.useWSA = true;
    options.action = &quot;http://services.mashup.wso2.org/usernameTokenService/ServiceInterface/demoRequest&quot;;
    options.username = &quot;yourUsername&quot;;
    options.password = &quot;yourPassword&quot;;
    options.useWSS = true;
    var payload = {firstParam}{secondParam};
    var result;
    try {
        request.open(options,&quot;https://mooshup.com/services/keith/usernameTokenService&quot;, false);
        request.send(payload);
        var response = request.responseE4X;
        result = response[&quot;return&quot;].toString();
    } catch (e) {
        system.log(e.toString(),&quot;error&quot;);
        return result = e.toString(); 
    }
    return result;
}
</pre><h2 id="&lt;span&gt;Invoking services using the dynamic version of the WSRequest Host Object&lt;/span&gt;">Invoking services using the dynamic version of the WSRequest Host Object</h2>
<p>Using the dynamic version of the WSRequest Host Object is much simpler than using the plain WSRequest Host Object. This is because the user needs not configure the WSRequest Host Object, the WSO2 Mashup Server will do it according to the details presented in the WSDL. Another important feature of the dynamic version of the WSRequest Host Object is that it can be used to invoke services which are secured using complex security scenarios with ease.</p>
<p>As with the plain version of the WSRequest Host Object, users need to provide the payload needed to access the service.</p>
<h3 id="&lt;span&gt;Invoking a service is a synchronous manner&lt;/span&gt;">Invoking a service is a synchronous manner</h3>
<p>Invoking a service in a synchronous manner is straightforward and can be done in the following manner.</p>
<pre class="prettyprint">
convertionRateUsingDynamicWSRequest.inputTypes={&quot;fromCurrency&quot; : &quot;string&quot;, &quot;toCurrency&quot; : &quot;string&quot;}; 
convertionRateUsingDynamicWSRequest.outputType=&quot;string&quot;; 
function convertionRateUsingDynamicWSRequest(fromCurrency, toCurrency){ 
    var request = new WSRequest();
    var payload = {fromCurrency}{toCurrency};
    var result;
    try {
        var service = new QName(&quot;http://www.webserviceX.NET/&quot;, &quot;CurrencyConvertor&quot;);
        request.openWSDL(&quot;http://www.webservicex.net/CurrencyConvertor.asmx?WSDL&quot;, false, new Array(), service, &quot;CurrencyConvertorSoap&quot;);
        request.send(&quot;ConversionRate&quot;, payload);
        var response = request.responseE4X;
        var ns = new Namespace('http://www.webserviceX.NET/');
        result = response.ns::[&quot;ConversionRateResult&quot;].toString();
    } catch (e) {
        system.log(e.toString(),&quot;error&quot;);
        return result = e.toString(); 
    }
    return result;
}
</pre><h3 id="&lt;span&gt;Invoking a service is a asynchronous manner&lt;/span&gt;">Invoking a service is a asynchronous manner</h3>
<p>This is similar to using the plain version of the WSRequset Host Object.</p>
<pre class="prettyprint">
convertionRateUsingDynamicWSRequestAsync.inputTypes={&quot;fromCurrency&quot; : &quot;string&quot;, &quot;toCurrency&quot; : &quot;string&quot;}; 
convertionRateUsingDynamicWSRequestAsync.outputType=&quot;string&quot;; 
function convertionRateUsingDynamicWSRequestAsync(fromCurrency, toCurrency){ 
    var request = new WSRequest();
    request.onreadystatechange = function() {
         handleResponse(request);
    };
    var payload = {fromCurrency}{toCurrency};
    var result;
    try {
        var service = new QName(&quot;http://www.webserviceX.NET/&quot;, &quot;CurrencyConvertor&quot;);
        request.openWSDL(&quot;http://www.webservicex.net/CurrencyConvertor.asmx?WSDL&quot;, true, new Array(), service, &quot;CurrencyConvertorSoap&quot;);
        request.send(&quot;ConversionRate&quot;, payload);
        result = &quot;Invoked the CurrencyConvertor service&quot;;        
    } catch (e) {
        system.log(e.toString(),&quot;error&quot;);
        return result = e.toString(); 
    }
    return result;
}

handleResponse.visible=false;
function handleResponse(request){
    if (request.readyState == 4) {
        var response = request.responseE4X;
        var ns = new Namespace('http://www.webserviceX.NET/');
        var result = response.ns::[&quot;ConversionRateResult&quot;].toString();
	system.log(result);
    }
}
</pre><h3 id="&lt;span&gt;Invoking a secured service&lt;/span&gt;">Invoking a secured service</h3>
<p>Provided the service you are invoking expresses its security requirements using WS-Security policy in the WSDL, the dynamic version of the WSRequest Host Object will help you access that service with ease. In order to access secured services you will need to set up the certificates needed (depending on the manner the third party service is secured).</p>
<p>For this example, let's access a service which is secured using security scenario 7 (Encrypt only - Username Token Authentication) in the WSO2 Mashup Server. This scenario expects users to send there username and password when accessing the service, they also need to encrypt the payload sent. The service <a href="http://mooshup.com/mashup.jsp?author=keith&amp;mashup=securedService">securedService</a> which is deployed on <a href="http://mooshup.com">mooshup.com</a> has been secured using scenario 7.</p>
<h4 id="&lt;span&gt;Setting up the certificates&lt;/span&gt;">Setting up the certificates</h4>
<p>Before securing a service or invoking a secured service, it is important to set up your personal keystore. Details on how this could be done can be found in the Mashup Server <a href="https://wso2.org/project/mashup/1.5.1/docs/index.html">documentation</a>. Refer the &quot;Keystore Management&quot; section.</p>
<p>Note : When creating the keystore please make sure that you use the &ldquo;-keyalg RSA&rdquo; option as well. This is needed for the encryption scenarios to work out of the box. e.g &ldquo;keytool -genkey -alias keith -keystore keith.jks -keyalg RSA&rdquo;.</p>
<p>In order to communicate with a service which requires your payload to be encrypted, you need to have the public key of that service. In our example, the secured service up on <a href="http://mooshup.com">mooshup.com</a> is secured using my keystore. Hence, you will need my public key to access this service. You can get it from <a href="http://wso2.org/files/cert.der">here</a>.<br>
</p>
<p>Note : In order to get a public key of a keystore you could use the keytool as follows,</p>
<p><code>keytool -export -keystore keith.jks -alias keith &gt; cert.der</code></p>
<p>cert.der would be the public key of this keystore.</p>
<p>Once you obtain this public key you will need to upload it to your keystore (In order to encrypt the request this public key is needed hence it should be available in your keystore). Please refer the &quot;Keystore Management&quot; section in the Mashup Server <a href="https://wso2.org/project/mashup/1.5.1/docs/index.html">documentation</a> for instructions on how this could be done. Lets assume that you uploaded it with the alias &ldquo;keithspublickey&rdquo;. Now we are all set to access this secured service.</p>
<pre class="prettyprint">
invokeSecuredService.inputTypes={&quot;firstParam&quot; : &quot;string&quot; , &quot;secondParam&quot; : &quot;string&quot;};
invokeSecuredService.outputType=&quot;string&quot;;
function invokeSecuredService(firstParam, secondParam) {
    var request = new WSRequest();
    var options = new Array();
    options.encryptionUser = &quot;keithspublickey&quot;;
    options.username = &quot;yourUsername&quot;;
    options.password = &quot;yourPassword&quot;;
    var payload = {firstParam}{secondParam};
    var result;
    try {
        var service = new QName(&quot;http://services.mashup.wso2.org/securedService&quot;, &quot;securedService&quot;);
        request.openWSDL(&quot;http://mooshup.com/services/keith/securedService?wsdl&quot;, false, options, service, &quot;SOAP12Endpoint&quot;);
        request.send(&quot;demo&quot;, payload);
        var response = request.responseE4X;
        result = response[&quot;return&quot;].toString();
    } catch (e) {
        system.log(e.toString(),&quot;error&quot;);
        return result = e.toString(); 
    }
    return result;
}
</pre><h1 id="Future Directions">Future Directions</h1>
<p>Although the WSO2 Mashup Server allows users to access external Web services with ease there are a few more improvements that could be done. These improvements would be available in future releases.</p>
<ul>
<li>Make changes to the WSRequest Host Object so that it will allow users to set a custom Security policy.</li>
<li>Allow users to provide and overide additional options when the dynamic version of the WSRequest Host Object is used. (For e.g ability to instract the use of HTTP Basic Authentication).</li>
</ul>
<h1 id="Conclusion">Conclusion</h1>
<p>This tutorial shows various ways and means the WSO2 Mashup Server provides access to external Web services. It also explains the pros and cons of each mechanism and gives code samples on how these mechanisms could be used effectively.</p>
<h3 id="Author">Author</h3>
<p>Keith Chapman, Senior Software Engineer, WSO2 Inc. <strong>keith</strong> at wso2 dot com</p>
    ]]></content>
  </entry>
  <entry>
    <title>WSO2 Carbon Cluster Configuration Language</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/articles/wso2-carbon-cluster-configuration-language" />
    <id>http://dist.wso2.org/library/articles/wso2-carbon-cluster-configuration-language</id>
    <published>2008-12-31T08:10:31+00:00</published>
    <updated>2009-01-06T09:17:18+00:00</updated>
    <author>
      <name>afkham_azeez</name>
    </author>
    <category term="Articles" />
    <category term="Intermediate" />
    <category term="Carbon" />
    <category term="Java" />
    <summary type="html"><![CDATA[<p><strong>Afkham Azeez</strong>, Architect and Product Manager for WSO2 WSAS, explains in detail the clustering configuration language used by <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a> based products.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p><strong>Afkham Azeez</strong>, Architect and Product Manager for WSO2 WSAS, explains in detail the clustering configuration language used by <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a> based products.</p>
<h2 id="Abstract">Abstract</h2>
<p>Clustering for High Availability &amp; Scalability is one of the main requirements of any enterprise deployment. This is also true for <a href="http://wso2.com">WSO2</a>'s open source SOA middleware products. However, configuring a cluster can be tricky. This article explains in detail the clustering configuration language used by WSO2 Carbon based products. If you haven't already read &quot;<a href="http://wso2.org/library/articles/introduction-wso2-carbon-clustering">Introduction to WSO2 Carbon Clustering</a>&quot;, I'd recommend you to read that article first.</p>
<h2>Table of Contents</h2>
<ul>
<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#1.%20Clustering%20Agent">1. Clustering Agent</a></li>
<li><a href="#2.%20ClusteringAgent%20Parameters">2. ClusteringAgent Parameters</a>
<ul>
<li><a href="#AvoidInitiation">AvoidInitiation</a></li>
<li><a href="#membershipScheme">membershipScheme</a></li>
<li><a href="#domain">domain</a></li>
<li><a href="#synchronizeAll">synchronizeAll</a></li>
<li><a href="#maxRetries">maxRetries</a></li>
<li><a href="#mcastAddress">mcastAddress</a></li>
<li><a href="#mcastPort">mcastPort</a></li>
<li><a href="#mcastFrequency">mcastFrequency</a></li>
<li><a href="#memberDropTime">memberDropTime</a></li>
<li><a href="#mcastBindAddress">mcastBindAddress</a></li>
<li><a href="#localMemberHost">localMemberHost</a></li>
<li><a href="#localMemberPort">localMemberPort</a></li>
<li><a href="#preserveMessageOrder">preserveMessageOrder</a></li>
<li><a href="#atmostOnceMessageSemantics">atmostOnceMessageSemantics</a></li>
<li><a href="#properties">properties</a></li>
</ul>
</li>
<li><a href="#3.%20State%20Management">3. State Management</a></li>
<li><a href="#4.%20Node%20Management">4. Node Management</a></li>
<li><a href="#5.%20Group%20Management">5. Group Management</a></li>
<li><a href="#6.%20%28Static%29%20Members">6. (Static) Members</a></li>
<li><a href="#Full%20Configuration">Full Configuration</a></li>
<li><a href="#Conclusion">Conclusion</a></li>
<li><a href="#References">References</a><a href="#About%20the%20Author"><br><br />
        </a></li>
</ul>
</ul>
<h2 id="Introduction">Introduction</h2>
<p>As we have seen in[1], <a href="http://ws.apache.org/axis2/">Apache Axis2</a> [2] is the base of WSO2 Carbon [3]. Hence, the clustering functionality of Apache Axis2 are inherited by WSO2 Carbon. In[1], we already looked at the concepts governing WSO2 Carbon clustering. In this article we will see how clustering has to be configured in the axis2.xml file.</p>
<p>The axis2.xml clustering configuration section has 6 main parts:</p>
<ol>
<li>Clustering Agent</li>
<li>Parameters</li>
<li>State Management</li>
<li>Node Management</li>
<li>Group Managment</li>
<li>Members</li>
</ol>
<p>In the rest of the article, we will look at these different sections in detail.</p>
<h2 id="1. Clustering Agent">1. Clustering Agent</h2>
<p>The ClusteringAgent is responsible for initializing all clustering related functionality of a Carbon member or node. Typically, the initialization of a node in a cluster is handled here. It is also responsible for getting a node to join the cluster. In the default Carbon/Axis2 clustering implementation, which is based on Apache Tribes [4], we use org.apache.axis2.clustering.tribes.TribesClusteringAgent.</p>
<h2 id="2. ClusteringAgent Parameters">2. ClusteringAgent Parameters</h2>
<p>In order to initialize the Clustering Agent, we require some parameters. Here are the parameters that are used in the current implementation:</p>
<h3 id="AvoidInitiation">AvoidInitiation</h3>
<p>This parameter indicates whether the cluster has to be automatically initalized when the AxisConfiguration is built. If set to &quot;true&quot;, the initialization will not be done at that stage, and some other party will have to explicitly initialize the cluster. In WSO2 Carbon, we have set this to &quot;true&quot;, since Carbon will decide when the cluster has to be initialized. In this case, the cluster is initialized after the server has completely started and the transports have been started.</p>
<h3 id="membershipScheme">membershipScheme</h3>
<p>The membership scheme used in this setup. The only values supported at the moment are &quot;multicast&quot; and &quot;wka&quot;.<br><br />
1. multicast - membership is automatically discovered using multicasting. In order for this to work, multicasting should be allowed in the network and all members in the cluster should use the same multicast address (as defined by the mcastAddress parameter) and the exact multicast port (as defined by the mcastPort parameter).<br><br />
2. wka - Well-Known Address based multicasting. Membership is discovered with the help of one or more nodes running at a Well-Known Address. New members joining a cluster will first connect to a well-known node, register with the well-known node and get the membership list from it. When new members join, one of the well-known nodes will notify the others in the group. When a member leaves the cluster or is deemed to have left the cluster, it will be detected by the Group Membership Service (GMS) using a TCP ping mechanism. WKA-based membership is necessary when multicast based membership discovery is not possible. For example, on Amazon EC2, multicasting is not allowed and there is no control over the IP address assigned to EC2 instances. Hence, in such a scenario, WKA-based membership discovery tends to be used.</p>
<h3 id="domain">domain</h3>
<p>The clustering domain/group. Note that the words &quot;domain&quot; and &quot;group&quot; are used synonymously. There will not be any interference between nodes in different groups. Messages received from members outside the group will generally be ignored. However, special messages, such as cluster management messages or membership messages from members outside the group will be allowed.</p>
<h3 id="synchronizeAll">synchronizeAll</h3>
<p>When a Web service request is received, and processed, should we update the states of all members in the cluster prior to the response being sent to the client? If the value of this parameter is set to &quot;true&quot;, the response to the client will be sent only after all members have been updated. Obviously, this can be time consuming. In some cases, where this overhead may not be acceptable, in which case the value of this parameter should be set to &quot;false&quot;. The risk in this case will be that all members will not be in the same state when the response is sent to the client. This condition will have to be handled by the user. In summary, this parameter defines whether we should synchronize the state of all members in the group before we send the response to the client or not.</p>
<h3 id="maxRetries">maxRetries</h3>
<p>This defines the maximum number of times we need to retry to send a message to a particular member, before giving up and considering that node to be faulty. After maxTries number of retries, we give up.</p>
<h3 id="mcastAddress">mcastAddress</h3>
<p>The multicast address to be used. This parameter will only be taken into consideration when the membershipScheme is set to &quot;multicast&quot;.</p>
<h3 id="mcastPort">mcastPort</h3>
<p>The multicast port to be used. This parameter will only be taken into consideration when the membershipScheme is set to &quot;multicast&quot;.</p>
<h3 id="mcastFrequency">mcastFrequency</h3>
<p>The frequency of sending membership multicast messages. The value should be specified in milliseconds. This parameter will only be taken into consideration when the membershipScheme is set to &quot;multicast&quot;.</p>
<h3 id="memberDropTime">memberDropTime</h3>
<p>The time interval within which, if a member does not respond, the member is deemed to have left the group. The value should be specified in milliseconds.</p>
<h3 id="mcastBindAddress">mcastBindAddress</h3>
<p>The IP address of the network interface to which the multicasting has to be bound to. Multicasting would be done using this interface.  This parameter will only be taken into consideration when the membershipScheme is set to &quot;multicast&quot;. Note that this can be different from the localMemberHost parameter. So we can listen for point-to-point messages on the localMemberHost network interface while listening for multicast messages on the network interface bound to the mcastBindAddress.</p>
<h3 id="localMemberHost">localMemberHost</h3>
<p>The host name or IP address of this member. This is the IP address advertised by this member when it joins the group and sends messages. This should be set to a valid value other than localhost or 127.0.0.1. In most cases, it would suffice to set it to the IP address bound to the network interface which is used for communicating with members in the group.</p>
<h3 id="localMemberPort">localMemberPort</h3>
<p>The TCP port used by this member. This is the port through which other members will contact this member.</p>
<h3 id="preserveMessageOrder">preserveMessageOrder</h3>
<p>Preserve message ordering. This will be done according to sender order.</p>
<h3 id="atmostOnceMessageSemantics">atmostOnceMessageSemantics</h3>
<p>Maintain atmost-once message processing semantics.</p>
<h3 id="properties">properties</h3>
<p>Properties specific to this member. These properties are are simply name-value pairs. When a member joins groups, these properties are bound to this member so that other members in the group can detect these properties. In the case of WSO2 Carbon, two member properties &quot;backendServerURL&quot; and &quot;mgtConsoleURL&quot; have been specified. These member properties are used for cluster management. The backendServerURL property is used to connect to the backend management Web services of this member using the front-end of the cluster manager. Similarly, if this member wishes to expose its own management console, it can do so by providing the &quot;mgtConsoleURL&quot; property. The backendServerURL property is specified using the &lt;property name=&quot;backendServerURL&quot; value=&quot;https://${hostName}:${httpsPort}/services/&quot;/&gt; entry. Here, ${hostName} signifies the &quot;hostName&quot; member property &amp; ${httpsPort} denotes the &quot;httpsPort&quot; member property. &quot;hostName&quot; &amp; &quot;httpsPort&quot; are two implicit member properties. &quot;httpPort&quot; is another implicit member property. Properties that have been previously declared can be used in subsequent property definitions. For example, we may define a new property as follows: &lt;property name=&quot;foo&quot; value=&quot;${backendServerULR}/foo&quot;/&gt;</p>
<h2 id="3. State Management">3. State Management</h2>
<p>The stateManager element needs to be enabled if you require to synchronize state across members in a cluster group. An implementation of the org.apache.axis2.clustering.state.StateManager needs to be provided as the value of the class attribute. In the default Apache Tribes based implementation, we provide the org.apache.axis2.clustering.state.DefaultStateManager class. The user can choose not to replicate certain properties. This is done by providing a property name pattern. For example, specifying &lt;exclude name=&quot;local_*&quot;/&gt; will exclude all properties having the names prefixed with local_ from replication, &lt;exclude name=&quot;*_local&quot;/&gt; will exclude all properties having the name suffixed with _local from replication. It follows that &lt;exclude name=&quot;*&quot;/&gt; excludes all properties from replication. Excluding all properties from replication may be useful when one needs to replicate only the properties in certain contexts. For example, if a user wishes to replicate properties only in the serviceContext, under the exclusion entries of org.apache.axis2.context.ConfigurationContext &amp; org.apache.axis2.context.ServiceGroupContext, the &lt;exclude name=&quot;*&quot;/&gt; entry should be added.</p>
<p>The exclusion patters under the defaults element will be applicable to all contexts. Hence, &lt;exclude name=&quot;local_*&quot;/&gt; under the &quot;defaults&quot; element means that all the properties prefixed with local_ in all the properties having names prefixed with local_ will be excluded from replication. Shown below is a sample &quot;stateManager&quot; entry.</p>
<pre class="prettyprint">
&lt;stateManager class=&quot;org.apache.axis2.clustering.state.DefaultStateManager&quot;
              enable=&quot;true&quot;&gt;
    &lt;replication&gt;
        &lt;defaults&gt;
            &lt;exclude name=&quot;local_*&quot;/&gt;
            &lt;exclude name=&quot;LOCAL_*&quot;/&gt;
        &lt;/defaults&gt;

        &lt;context class=&quot;org.apache.axis2.context.ConfigurationContext&quot;&gt;
            &lt;exclude name=&quot;UseAsyncOperations&quot;/&gt;
            &lt;exclude name=&quot;SequencePropertyBeanMap&quot;/&gt;
         &lt;/context&gt;

        &lt;context class=&quot;org.apache.axis2.context.ServiceGroupContext&quot;&gt;
            &lt;exclude name=&quot;my.sandesha.*&quot;/&gt;
        &lt;/context&gt;

        &lt;context class=&quot;org.apache.axis2.context.ServiceContext&quot;&gt;
            &lt;exclude name=&quot;my.sandesha.*&quot;/&gt;
        &lt;/context&gt;
    &lt;/replication&gt;
&lt;/stateManager&gt;
</pre><h2 id="4. Node Management">4. Node Management</h2>
<p>The nodeManager element needs to be enabled in order to have node management functionality. An implementation of the org.apache.axis2.clustering.NodeManager interface needs to be provided as the value of the class attribute.</p>
<pre class="prettyprint">
&lt;nodeManager class=&quot;org.apache.axis2.clustering.management.DefaultNodeManager&quot;
             enable=&quot;true&quot;/&gt;
</pre><h2 id="5. Group Management">5. Group Management</h2>
<p>When this member is deployed as a cluster manager, the groupManagement element needs to be enabled. A group management agent, which is an instance of the org.apache.axis2.clustering.management.GroupManagementAgent interface, needs to be specified for each group (applicationDomain) that is being managed. The example configuration below shows how cluster management has been enabled for two groups; group1 and group2.</p>
<pre class="prettyprint">
&lt;groupManagement enable=&quot;true&quot;&gt;
    &lt;applicationDomain name=&quot;group1&quot;
                       description=&quot;This is the first group&quot;
                       agent=&quot;org.apache.axis2.clustering.management.DefaultGroupManagementAgent&quot;/&gt;
    &lt;applicationDomain name=&quot;group2&quot;
                       description=&quot;This is the second group&quot;
                       agent=&quot;org.apache.axis2.clustering.management.DefaultGroupManagementAgent&quot;/&gt;
&lt;/groupManagement&gt;
</pre><h2 id="6. (Static) Members">6. (Static) Members</h2>
<p>The members element is used for specifying static or well-known members. The hostName and the primary port of these members need to be specified. the sample member configuration below shows two static members with different IP addresses and ports:</p>
<pre class="prettyprint">
&lt;members&gt;
    &lt;member&gt;
       &lt;hostName&gt;10.100.1.202&lt;/hostName&gt;
       &lt;port&gt;4000&lt;/port&gt;
    &lt;/member&gt;
    &lt;member&gt;
       &lt;hostName&gt;10.100.1.154&lt;/hostName&gt;
       &lt;port&gt;4001&lt;/port&gt;
    &lt;/member&gt;
&lt;/members&gt;
</pre><h2 id="Full Configuration">Full Configuration</h2>
<p>Shown below is a typical clustering configuration in WSO2 Carbon.</p>
<pre class="prettyprint">
&lt;clustering class=&quot;org.apache.axis2.clustering.tribes.TribesClusteringAgent&quot; enable=&quot;false&quot;&gt;
    &lt;parameter name=&quot;AvoidInitiation&quot;&gt;true&lt;/parameter&gt;
    &lt;parameter name=&quot;membershipScheme&quot;&gt;multicast&lt;/parameter&gt;
    &lt;parameter name=&quot;domain&quot;&gt;wso2.carbon.domain&lt;/parameter&gt;
    &lt;parameter name=&quot;synchronizeAll&quot;&gt;true&lt;/parameter&gt;
    &lt;parameter name=&quot;maxRetries&quot;&gt;10&lt;/parameter&gt;
    &lt;parameter name=&quot;mcastAddress&quot;&gt;228.0.0.4&lt;/parameter&gt;
    &lt;parameter name=&quot;mcastPort&quot;&gt;45564&lt;/parameter&gt;
    &lt;parameter name=&quot;mcastFrequency&quot;&gt;500&lt;/parameter&gt;
    &lt;parameter name=&quot;memberDropTime&quot;&gt;3000&lt;/parameter&gt;
    &lt;parameter name=&quot;mcastBindAddress&quot;&gt;127.0.0.1&lt;/parameter&gt;
    &lt;parameter name=&quot;localMemberHost&quot;&gt;127.0.0.1&lt;/parameter&gt;
    &lt;parameter name=&quot;localMemberPort&quot;&gt;4000&lt;/parameter&gt;
    &lt;parameter name=&quot;preserveMessageOrder&quot;&gt;true&lt;/parameter&gt;
    &lt;parameter name=&quot;atmostOnceMessageSemantics&quot;&gt;true&lt;/parameter&gt;
    &lt;parameter name=&quot;properties&quot;&gt;
        &lt;property name=&quot;backendServerURL&quot; value=&quot;https://${hostName}:${httpsPort}/services/&quot;/&gt;
        &lt;property name=&quot;mgtConsoleURL&quot; value=&quot;https://${hostName}:${httpsPort}/&quot;/&gt;
    &lt;/parameter&gt;

    &lt;members&gt;
        &lt;member&gt;
            &lt;hostName&gt;127.0.0.1&lt;/hostName&gt;
            &lt;port&gt;4000&lt;/port&gt;
        &lt;/member&gt;
        &lt;member&gt;
            &lt;hostName&gt;127.0.0.1&lt;/hostName&gt;
            &lt;port&gt;4001&lt;/port&gt;
        &lt;/member&gt;
    &lt;/members&gt;
<p>    &lt;groupManagement enable=&quot;false&quot;&gt;<br>        &lt;applicationDomain name=&quot;apache.axis2.application.domain&quot;<br>                           description=&quot;Axis2 group&quot;<br>                           agent=&quot;org.apache.axis2.clustering.management.DefaultGroupManagementAgent&quot;/&gt;<br>    &lt;/groupManagement&gt;</p><p>    &lt;nodeManager class=&quot;org.apache.axis2.clustering.management.DefaultNodeManager&quot;<br>                 enable=&quot;true&quot;/&gt;<br>    &lt;stateManager class=&quot;org.apache.axis2.clustering.state.DefaultStateManager&quot;<br>                  enable=&quot;true&quot;&gt;<br>        &lt;replication&gt;<br>           &lt;defaults&gt;<br>              &lt;exclude name=&quot;local_*&quot;/&gt;<br>              &lt;exclude name=&quot;LOCAL_*&quot;/&gt;<br>           &lt;/defaults&gt;<br>           &lt;context class=&quot;org.apache.axis2.context.ConfigurationContext&quot;&gt;<br>                &lt;exclude name=&quot;UseAsyncOperations&quot;/&gt;<br>                &lt;exclude name=&quot;SequencePropertyBeanMap&quot;/&gt;<br>            &lt;/context&gt;<br>            &lt;context class=&quot;org.apache.axis2.context.ServiceGroupContext&quot;&gt;<br>                &lt;exclude name=&quot;my.sandesha.*&quot;/&gt;<br>            &lt;/context&gt;<br>            &lt;context class=&quot;org.apache.axis2.context.ServiceContext&quot;&gt;<br>                &lt;exclude name=&quot;my.sandesha.*&quot;/&gt;<br>            &lt;/context&gt;<br>        &lt;/replication&gt;<br>    &lt;/stateManager&gt;<br><br>&lt;/clustering&gt;
</pre><h2 id="Conclusion">Conclusion</h2>
<p>In this article, we had a detailed look at the clustering configuration language used in WSO2 Carbon and Apache Axis2. Knowledge of these configuration parameters are essential when it comes to configuring a cluster in an enterprise deployment setup.</p>
<h2 id="References">References</h2>
<ol>
<li>Introduction to WSO2 Carbon Clustering, <a href="http://wso2.org/library/articles/introduction-wso2-carbon-clustering">http://wso2.org/library/articles/introduction-wso2-carbon-clustering</a></li>
<li>Apache Axis2, <a href="http://ws.apache.org/axis2/">http://ws.apache.org/axis2/</a></li>
<li>WSO2 Carbon, <a href="https://wso2.org/projects/carbon/">https://wso2.org/projects/carbon/</a></li>
<li>Apache Tribes, <a href="http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html">http://tomcat.apache.org/tomcat-6.0-doc/tribes/introduction.html</a></li>
</ol>
<h2 id="About the Author">About the Author</h2>
<p>Afkham Azeez is the Architect &amp; Product Manager WSO2 WSAS. He also designed and developed the Axis2 clustering implementation. Currently, he is working on making Apache Axis2 Web services and WSO2 products scale automatically on cloud infrastructures.</p>
    ]]></content>
  </entry>
  <entry>
    <title>ebook: Making Good SOA Great - The WSO2 Story of Componentization</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/ebook/ebook-making-good-soa-great-wso2-story-componentization" />
    <id>http://dist.wso2.org/library/ebook/ebook-making-good-soa-great-wso2-story-componentization</id>
    <published>2008-12-23T13:52:16+00:00</published>
    <updated>2008-12-23T14:09:15+00:00</updated>
    <author>
      <name>ayanthi</name>
    </author>
    <category term="ebook" />
    <category term="Carbon" />
    <summary type="html"><![CDATA[<p>A new ebook introducing WSO2's revolutionary <a href="/projects/carbon">Carbon</a> product is now available on OT.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>A new ebook introducing WSO2's revolutionary <a href="/projects/carbon">Carbon</a> product is now available on OT.</p>
<!--break-->
<p>The ebook takes reader through the middleware journey to introduce WSO2 Carbon - the unifying platform that underpins SOA middleware componentization.</p>

<p>ebook: <a href="/project/carbon/making_good_soa_great.pdf">making_good_soa_great.pdf (4.77 MB)</p>    ]]></content>
  </entry>
  <entry>
    <title>Podcast on WSDL 2.0 - Part Two</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/podcasts/podcast-wsdl-2-0-part-two" />
    <id>http://dist.wso2.org/library/podcasts/podcast-wsdl-2-0-part-two</id>
    <published>2008-12-18T09:20:55+00:00</published>
    <updated>2009-01-07T02:09:52+00:00</updated>
    <author>
      <name>ayanthi</name>
    </author>
    <category term="Podcasts" />
    <category term="WSDL 2.0" />
    <summary type="html"><![CDATA[<p>In this podcast (part 2 of a 2 part series), <strong>Keith Chapman</strong> - a WSO2 Tech Lead - talks to Oxygen Tank about WSDL support for Representational State Transfer (REST).</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>In this podcast (part 2 of a 2 part series), <strong>Keith Chapman</strong> - a WSO2 Tech Lead - talks to Oxygen Tank about WSDL support for Representational State Transfer (REST).</p>
<!--break-->
<h2><strong>Podcast</strong>: <a href="/files/podcasts/wsdl2-by-keith-part-2.mp3" onClick="javascript: pageTracker._trackPageview('/downloads/podcasts/wsdl2-by-keith-part-1.mp3'); "> wsdl2-by-keith-part-2.mp3</a></h2>

<p><strong>Related Resources</strong></p>
<ul>
<li>Listen to <a href="http://wso2.org/library/podcasts/podcast-wsdl">Podcast on WSDL 2.0 - Part One</a></li>
</ul>    ]]></content>
  </entry>
  <entry>
    <title>Slide Presentation: WSO2 Carbon - Middleware à la carte</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/presentations/presentation-wso2-carbon-middleware-la-carte" />
    <id>http://dist.wso2.org/library/presentations/presentation-wso2-carbon-middleware-la-carte</id>
    <published>2008-12-18T03:10:33+00:00</published>
    <updated>2008-12-18T03:17:57+00:00</updated>
    <author>
      <name>ayanthi</name>
    </author>
    <category term="Presentations" />
    <category term="Carbon" />
    <summary type="html"><![CDATA[<p>A slide presentation with an overview of the new WSO2 Carbon architecture is now available from the WSO2's developer portal Carbon project page.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>A slide presentation with an overview of the new WSO2 Carbon architecture is now available from the WSO2's developer portal Carbon project page.</p>
<!--break-->
<p>This presentation briefly illustrates the WSO2's journey towards componentization, and takes a look at how WSO2 Carbon unifies the entire SOA platform with its offerings to customize SOA deployments.</p>

<p>Slide Presentation: <a href="http://wso2.org/projects/carbon">WSO2 Carbon - Middleware à la carte (303 KB)</p>    ]]></content>
  </entry>
  <entry>
    <title>Podcast on WSO2 Carbon</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/podcasts/podcast-wso2-carbon" />
    <id>http://dist.wso2.org/library/podcasts/podcast-wso2-carbon</id>
    <published>2008-12-11T07:08:14+00:00</published>
    <updated>2008-12-14T03:24:35+00:00</updated>
    <author>
      <name>ayanthi</name>
    </author>
    <category term="Podcasts" />
    <category term="Carbon" />
    <summary type="html"><![CDATA[<p>In this podcast, <strong><a href="http://wso2.com/about/leadership/sanjiva_weerawarana/">Sanjiva Weerawarana</a></strong> (Founder, Chairman &amp; CEO, WSO2 Inc.) and <strong><a href="">Samisa Abeysinghe</a></strong> (Director of Engineering, WSO2 Inc) discuss <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a> - WSO2's unified SOA platform that componentizes SOA middleware that serves business agility enterprises demand.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>In this podcast, <strong><a href="http://wso2.com/about/leadership/sanjiva_weerawarana/">Sanjiva Weerawarana</a></strong> (Founder, Chairman &amp; CEO, WSO2 Inc.) and <strong><a href="">Samisa Abeysinghe</a></strong> (Director of Engineering, WSO2 Inc) discuss <a href="http://wso2.org/projects/carbon">WSO2 Carbon</a> - WSO2's unified SOA platform that componentizes SOA middleware that serves business agility enterprises demand.</p>
<p><strong>Podcast</strong>: <a href="/files/podcasts/carbon podcast.mp3">carbon podcast.mp3 </a></p>
    ]]></content>
  </entry>
  <entry>
    <title>Reliable Messaging with Sandesha2/C</title>
    <link rel="alternate" type="text/html" href="http://dist.wso2.org/library/3429" />
    <id>http://dist.wso2.org/library/3429</id>
    <published>2008-03-31T08:53:32+00:00</published>
    <updated>2009-01-06T11:49:32+00:00</updated>
    <author>
      <name>damitha</name>
    </author>
    <category term="Articles" />
    <category term="Intermediate" />
    <category term="C" />
    <category term="WS-Specifications" />
    <summary type="html"><![CDATA[<p>Reliability is a must for certain Web services users. Web services engines need to implement <a href="http://wso2.org/files/wsrm-1.1-spec-os-01-e1.pdf">Web Services Reliable Messaging specification</a> to provide reliability to application messages sent using it. However, specifications do not provide a reliable programming interface like JMS (Java Messaging Service). It specifies just a wire format for SOAP messages intended to be sent reliably. Read this article to find out how Sandesha2/C implements reliable messaging. <strong>Damitha Kumarage</strong> explains.</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>Reliability is a must for certain Web services users. Web services engines need to implement <a href="http://wso2.org/files/wsrm-1.1-spec-os-01-e1.pdf">Web Services Reliable Messaging specification</a> to provide reliability to application messages sent using it. However, specifications do not provide a reliable programming interface like JMS (Java Messaging Service). It specifies just a wire format for SOAP messages intended to be sent reliably. Read this article to find out how Sandesha2/C implements reliable messaging. <strong>Damitha Kumarage</strong> explains.</p>
<h2>Introduction</h2>
<p>Axis2/C is a Web services engine that is gaining popularity as a robust, feature rich Web services engine and is implemented in C. Sandesha2/C provides reliability for SOAP messages sent using Axis2/C by implementing the WS-Reliable Messaging specification. It plugs into Axis2/C as a standard module with two handler implementations within it, fitting into the Axis2/C in/out handler chains as specified by the module configuration. They provide implementation for RMSource and RMDestination specified in the specification. This implementation support both RM <a href="http://wso2.org/files/wsrm-1.0-specification.pdf">1.0</a> and <a href="http://wso2.org/files/wsrm-1.1-spec-os-01-e1.pdf">1.1</a> specifications. It is interoperable with Microsoft .NET and Sandesha2/Java implementations.</p>
<h3>Table of Contents</h3>
<ul>
<li><a href="#Reliability">Reliability provided by Sandesha2/C</a></li>
<li><a href="#Start">Let's do it with Sandesha2/C</a></li>
<li><a href="#Oneway">One way</a></li>
<li><a href="#Dual">Two way dual channel</a></li>
<li><a href="#Single">Two way single channel</a></li>
<li><a href="#Persistant">Enhanced Reliability</a></li>
<li><a href="#Future">Future</a></li>
<li><a href="#Summary">Summary</a></li>
<li><a href="#Resources">Resources</a></li>
</ul>
<h2 id="Reliability">Reliability provided by Sandesha2/C</h2>
<p>Underlying transport for sending SOAP messages could be any valid transport supported by the SOAP engine. It could be http, https, smtp, xmpp etc. We can't always expect the underlying transport to be reliable. Infact, http - the most widely used transport for SOAP is inherently unreliable. Also, we can't always expect that SOAP messages we send goes from a client to a service node. There could be many intermediaries between which the message hops, before it reaches it's final destination. We cannot predict whether the transport between any two intermediaries is reliable or not.</p>
<p>There are several aspects to reliability when transmitting SOAP messages. First, the sender of messages need to know whether he intends to know if the sent messages are actually received by the recipient. In that case, he needs to be acknowledged by the receiver. If the sender is not acknowledged within a predefined time frame then the sender should be able to resend the message until he receives an acknowledgment. The application environment that's sending out the message could be unreliable due to several reasons. The network could be broken, the server could be shutdown etc etc. This level of reliability is required from the specification and is provided by Sandesha2/C.</p>
<p>Second, there may exist the need for delivery assurance that the application message hits the target service exactly once. Although this is not required by the specification, it could be provided by a SOAP engine and Sandesha2/C do that for Axis2/C.</p>
<p>Thirdly, there may also exist the need for assurance that the messages are fed into the target service in the order they were intended to by the sender. Again, this is not required by the specification but the server could provide for it. This is in the TODO task list for Sandesha2/C.</p>
<p>Forth, suppose that the server shuts down before a sequence is completed. If the SOAP engine's reliability implementation provides a permanent storage mechanism to store the information related to the sequence(specifically at RMDestination), the sequence could be revoked when the server come back up. This level of reliability is not mandated by the reliable messaging specification. But Sandesha2/C has gone a step forward and implements this.</p>
<p>Finally, again, although not mandated by the specification, transaction support integration is deemed as necessary for certain business requirements. Sandesha2/C has no plans to support this yet.</p>
<h2 id="Start">Let's do it with Sandesha2/C</h2>
<p>Before installing Sandesha2/C, you need Axis2/C installed and configured in your system. For further information on installing and configuring Axis2/C see <a href="http://ws.apache.org/axis2/c/docs/index.html">here</a>. After installing Axis2/C make sure that AXIS2C_HOME environment variable is set pointing to the Axis2/C installation folder(repository). You can download Sandesha2/C from <a href="http://ws.apache.org/sandesha/sandesha2/c/download.cgi">here</a>. After downloading do</p>
<pre>
./configure --prefix=${AXIS2C_HOME} --enable-static=no
--with-axis2=${AXIS2C_HOME}/include/axis2-1.3.0</pre><pre>
make</pre><pre>
make install</pre><p>This will install Sandesha2/C into Axis2/C repository. After installing you will find following in AXIS2C_HOME repository.</p>
<pre>
$AXIS2C_HOME/modules/sandesha2</pre><pre>
$AXIS2C_HOME/services/RMSampleService</pre><pre>
$AXIS2C_HOME/lib/libsandesha2_client.so</pre><pre>
$AXIS2C_HOME/bin/samples/sandesha2</pre><p>For Windows operating system the instructions for installing is as follows:</p>
<ol>
<li>Unzip the source zip file and go into the extracted folder's build\win32 subfolder.</li>
<li>Edit the configure.in with your binary locations.</li>
<li>To set necessary environment variables on your cmd.exe run vcvars32.bat file.</li>
<li>Run<br />
<pre>
nmake dist</pre><p>    command. This will build the Sandesha2/C binary and samples to a directory \build\sandesha2</li>
<li>Now copy \build\sandesha2\Sandesha2 directory to your &lt;AXIS2C_HOME&gt;\modules directory</li>
<li>Copy \build\sandesha2\bin\samples\RMSampleService to &lt;AXIS2C_HOME&gt;\services directory</li>
</ol>
<p>Additionally, both on Linux and Windows platforms, you need to make sure that you add the RMPhase to the flows in axis2.xml in your repository directory pointed to by AXIS2C_HOME; environment varible. To do this add the following entry into inflow, outflow INfaultflow and Outfaultflow.</p>
<pre>
&lt;phase name=&quot;RMPhase&quot;/&gt;</pre><p>For more information on installing Sandesha2/C see <a href="http://ws.apache.org/sandesha/sandesha2/c/docs/index.html">Sandesha2/C documentation</a>. <br><br />
Note: If you download WSF/C then you need not worry downloading and installing separate packages for Axis2/C and Sandesha2/C and then integrating them. WSF/C is an integrated Web services platform which provides the user many Web services specific facilities in one package.</p>
<p>RMSampleService is an Axis2/C service engaged with Sandesha2/C for demonstration purposes. Engaging Sandesha2/C to a service is done by adding following line to services.xml.</p>
<pre>
&lt;module ref=&quot;sandesha2&quot;/&gt;</pre><p>If there is a need to engage Sandesha2/C to every service in the repository, you need to put this entry into Axis2/C main configuration file(axis2.xml).</p>
<p>There are two Reliable Messaging specifications released so far from W3C. They are WS-Reliable messaging version 1.0 and version 1.1. Sandesha2/C is designed to support both of these versions.</p>
<p>When sending SOAP messages, there are basically four message exchange patterns(MEP) possible. In-Only, In-Out, Out-Only, Out-In. These falls into two broader categories namely a request-response(two way) pattern, and a one-way pattern, which a communication protocol wishing to establish a communication channel is required to support. Currently, Sandesha2/C supports only SOAP over HTTP transport protocol. Usually, a service client using Axis2/C client API can send messages in several ways. He can use one of the following AXIS2/C client API functions to send messages:</p>
<pre>
axis2_svc_client_fire_and_forget()</pre><pre>
axis2_svc_client_send_robust()</pre><pre>
axis2_svc_client_send_receive()</pre><pre>
axis2_svc_client_send_receive_non_blocking().</pre><p>The first two falls into one-way pattern and the last two to two-way pattern. The difference between the first and second, is that in the second pattern, if the server triggers a SOAP fault this function would report an error back to the caller.</p>
<p>The request-response messages could be further categorized into synchronous and asynchronous. In synchronous mode the sender is blocked for a response from the server, whereas in the asynchronous mode the user is not. The third function above is synchronous and the fourth asynchronous.</p>
<p>Keeping those things about Axis2/C service client API in mind, let's now turn into sending messages reliably using Sandesha2/C. For an existing client which is not reliable, adding reliability is simple. You need to make sure addressing is enabled by:</p>
<pre>
axis2_svc_client_engage_module(svc_client, env,
AXIS2_MODULE_ADDRESSING);</pre><p>and you need to add a line to engage Sandesha2/C to the client by.</p>
<pre>
axis2_svc_client_engage_module(svc_client, env, &quot;sandesha2&quot;);</pre><p>Today, SOAP over HTTP protocol is dominant for sending/receiving SOAP messages. However, doing two-way messaging using SOAP over HTTP posesses interesting issues. We don't have a contactable URI in some situations, like when sitting behind a firewall. In that case, there is a replay model implemented for Sandesha2/C, that could be used to do two-way messaging which uses the HTTP back channel to send messages from the server.</p>
<p>Now, let's go into detail with each of these.</p>
<h2 id="Oneway">One way</h2>
<p>Once we engage a service and a client with Sandesha2/C as described above, the client and server exchanges messages reliably. While we proceed further, we will get clarified of certain elements pertaining to reliable messaging. <strong>Sequence</strong> is an element embedded into messages to make it identify as belonging to a certain sequence of messages. It has a <strong>SequenceID</strong> element to uniquely identify the sequence. RMSource and RMDestination are the words defined by RM Specification for sequence client and server. Here, sequence client means the one who initiated the sequence. RMSource and RMDestination should not be interchanged for the application client/requester and server/service. In two way reliable messaging, for the response sequence RMSource actually resides in the application server side and RMDestination actually resides in the application client side.</p>
<p><img alt="" src="http://wso2.org/files/reliable-messaging-1.png"></p>
<p>Once the message is sent by the client application, it is intercepted by the Sandesha2/C out handler that sits in the RMPhase of the outflow. It would temporarily hold this application message until registering a sequence with the server. Registering a sequence means sending a RM specific message called <strong>CreateSequence</strong> to the server with an <strong>AcksTo</strong> element and receiving from server a <strong>CreateSequenceResponse</strong> message which contain a <strong>SequenceID</strong>. <strong>AcksTo</strong> element contains an endpoint URL to which the acknowledgment messages must be sent from server. Thereafter all the application messages sent from client should contain this sequence id to mark that the message belongs to an established sequence between client and server until the client specifically terminate the sequence. In addition, each application message belonging to a sequence should have a <strong>MessageNumber</strong> element to mark the order of the message within the sequence. There could be any number of application messages associated with a sequence. Once the client receive the CreateSequenceResponse message it can send the temporarily held application message marked with the sequence id. Server could send an acknowledgment for this message to the specified URL in AcksTo element. In HTTP if the AcksTo URL is anonymous as it happen in most cases then the acknowledgment messages is sent in the HTTP back channel.</p>
<p>It is not required to send an acknowledgment for each application message from the server. Server can send one acknowledgment message containing an AcknowledgementRange element. <strong>AcknowledgementRange</strong> element contain the message numbers for all the messages so far received by the server. However a client could specifically request an acknowledgment request element in the sending message which should be promptly responded with an acknowledgment by the server.</p>
<p>When the client know that it has sent all the application messages intended for the server it can inform the server so by sending an application <strong>TerminateSequence</strong> message. In the RM 1.1 this will be responded by a <strong>TerminateSequenceResponse</strong> message.</p>
<p>It should be noted that all the strong typed words in the above paragraphs belongs to the WSRM namespace defined by the specification. You can define to which Reliable messaging version(1.0 or 1.1) this namespace should belong to by adding following code to the client application</p>
<pre>
property = axutil_property_create_with_args(env, 3, 0, 0,
SANDESHA2_SPEC_VERSION_1_0);
if(property)
{
    axis2_options_set_property(options, env,
    SANDESHA2_CLIENT_RM_SPEC_VERSION, property);
}</pre><p>So far I have explained the all good scenario where nothing goes wrong between RM source and RM destination. What happens if network is broken and your second message in the sequence is not received by the destination?. Well the sever does not acknowledge for the second message you would say. yes that's correct. Then what will RM source do when it does not receive acknowledgment for the second message?. It will simply resend the application message number 2. But for how many times?. If the connection is broken indefinitely what happen?. In this case the client will resend the application message for a predefined number of times. The number of resends in such cases are determined by the RM Policy. Also the delay between sends is determined by the RetransmissionInterval by the Policy. Policy related xml configuration in the server or client repository should be edited before deployment to change the default values. Also there is a policy parameter called InactivityTimeout in Policy which is used to determine sequence timeout.</p>
<h2 id="Dual">Two way dual channel</h2>
<p>Two way messaging is basically understood as two one-way scenarios described above. One from client to server and other from server to client. All the request application messages from client to server belong to the sequence initiated by the client. All the response application messages from server to client belongs to the sequence initiated by the server. It should be understood that in the client there is both RMSource and RMDestination and so in the server side.</p>
<p><img alt="" src="http://wso2.org/files/reliable-messaging-2.png"></p>
<h2 id="Single">Two way single channel</h2>
<p>Adding reliablity to a set of related application messages should not be a burden to the original sender or a receiver. If we increase RM specific messages such as CreateSequence, CreateSequenceResponse, Acknowledgement messages etc it would greatly reduce network efficiency. So if we reduce such RM specific messages to a minimum it would be a great way of providing reliability for the applications. One such mechanism is SequenceOffer element you can incorporate into your CreateSequence message. This element containa a RMSource generated sequence id, which would be offered to the RMDestination for acceptance. If the destination accept this by responding with an Accept element included in its CreateSequeceResponse message, then it does not need to specially send a CreateSequence message from server to client because response sequence id is already established by accepting the sequence id offered from the source.</p>
<p>This feature opens way for an application who has only single http channel to communicate in request/response pattern. For example, when we are behind a firewall and need to do two way messaging with our server reliably. Of course if there is no reliability, we can use the http back channel to send response messages synchronously. When reliability is on, we can still use the back channel to send response messages and acknowledgments in the http back channel. But how the server send us a CreateSequence message to establish a sequence to send response messages from server?\ We don't have a contactable URL behind our firewall to do that. You have the answer in sequence offer concept described above, because we can use SequenceOffer element in our CreateSequence message sent from client and avoid a CreateSequence message from server.</p>
<p>There is another method which could be used to do reliable messaging in a two way single channel using <a href="http://wso2.org/files/wsmc-1.1-spec-cd-01.pdf">MakeConnection specification</a>. In this method once the sequence is established Sandesha2/C starts a new thread for sending a new message called MakeConnection. This message body contains nothing more than an identifier element containing the sequence id offered for response sequence. HTTP back channel for this message provides a channel for response messages from server. For example, all application response messages from server and a terminate message from server are communicated through this back channel. The frequency of sending the MakeConnection message is determined by the PollingWaitTime Policy paramter.</p>
<h2 id="Persistant">Enhanced Reliability</h2>
<p>Although not mandated by the specification Sandesha2/C provides a persistant storage mechanism to store sequence information in an sqlite embedded database. Because of this even in a server crash and recovery scenario the on going sequences can continue because sequence information are stored in a database. Sandesha2/C also provides 'exactly once' feature by dropping duplicate messages received by the destination.</p>
<h2 id="Future">Future</h2>
<p>As explained earlier on, reducing the number of RM-specific messages greatly improves the network performance, when reliable messaging is engaged. As a future direction, it is planned to support AckRequested element, using which, we can configure to get Acknowledgement messages only when requested by the client.</p>
<p>Additionally, server could be configured to send acknowledgment messages only for missing messages. It does so by sending a <strong>Nack</strong> element to the sender that contains missing message numbers. This is intended as a future enhancement for Sandesha2/C. Also, it is planned to support Policy integration and security integration in to Sandesha2/C. The message ordering will also be supported by future versions.</p>
<p>More, there is plans to incorporate a sequence message monitoring mechanism tool into Sandesha2/C, so that one could easily track sequence messages from a database.</p>
<h2 id="Summary">Summary</h2>
<p>Sandesha2/C is the reliable messaging implementation for Axis2/C Web services engine. It could be easily integrated into your existing application written using Axis2/C to provide reliability with minimum effort. Sandesha2/C currently supports HTTP transport and has future plans to support other transports (supported by Axis2/C). It supports both one-way and two-way message exchange patterns. In addition, it provides a mechanisms to do two-way messaging using a single http channel between a client and a server both for RM 1.0 and RM 1.1. Sandesha2/C also features a persistant storage mechanism to support server shutdowns during a sequence progress.</p>
<h3 id="Resources"><a name="res"></a>Resources</h3>
<ol>
<li><a href="../../../../projects/wsf/c" name="wsfc">WSO2 WSF/C </a>-     WSO2 WSF/C is an Open Source framework for providing and consuming Web     services</li>
<li><a href="http://ws.apache.org/axis2/c/">Axis2/C</a>- Axis2/C is an     Apache Web Services Platform implemented in C language around which the     WSO2 WSF/C is built.</li>
<li><a href="http://ws.apache.org/sandesha/sandesha2/c/">Sandesha2/C</a>-     Sandesha2/C is an implementation of WS Reliable Messaging Specification     in C language. It is part of WSO2 WSF/C framework.</li>
<li><a href="https://svn.apache.org/repos/asf/webservices/sandesha/trunk/c">Sandesha2/C svn download </a>-     You can download latest source for Sandesha2/C here.</li>
<li><a href="http://www.infoq.com/articles/fremantle-wsrm-introduction">An     Introduction to Web Services Reliable Messaging</a>.</li>
</ol>
<h4 id="Author">Author</h4>
<p>Damitha Kumarage, Senior Software Engineer at WSO2 and committer for Apache Software Foundation. damitha at wso2 dot com</p>
    ]]></content>
  </entry>
</feed>
