You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ch...@apache.org on 2006/10/16 13:58:04 UTC
svn commit: r464454 [2/2] -
/webservices/axis2/trunk/c/xdocs/docs/userguide.html
Modified: webservices/axis2/trunk/c/xdocs/docs/userguide.html
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/xdocs/docs/userguide.html?view=diff&rev=464454&r1=464453&r2=464454
==============================================================================
--- webservices/axis2/trunk/c/xdocs/docs/userguide.html (original)
+++ webservices/axis2/trunk/c/xdocs/docs/userguide.html Mon Oct 16 04:58:02 2006
@@ -1,2124 +1,993 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<?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>
<head>
-
-
-
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-
-
-
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
-
-
-
-
-
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Axis2/C User's Guide</title>
- <meta name="generator" content="amaya 8.5, see http://www.w3.org/Amaya/">
+ <meta name="generator" content="amaya 9.2.1, see http://www.w3.org/Amaya/"
+ />
</head>
-
-<body>
-
-
-<h1>Axis2/C User's Guide</h1>
-
+<body xml:lang="en">
+<h1>Apache Axis2/C User's Guide</h1>
<h2>Content</h2>
-
-
<ul>
-
-
- <li>
-
- <p><a href="#Introduction">Introduction</a></p>
-
-
-
+ <li><p><a href="#Introduction">Introduction</a></p>
<ul>
-
-
<li><a href="#What_is_Axis2_">What is Axis2/C?</a></li>
-
-
-
</ul>
-
-
</li>
-
-
- <li><a href="#Web_Services_Using_Axis2">Web
-Services Using Axis2/C</a>
-
+ <li><a href="#Web_Services_Using_Axis2">Web Services Using Axis2/C</a>
<ul>
-
-
- <li><a href="#Writing_Web_Services_Using_Axis2_C">Writing
-Web Services Using Axis2/C</a>
-
+ <li><a href="#Writing_Web_Services_Using_Axis2_C">Writing Web Services
+ Using Axis2/C</a>
<ul>
-
-
- <li><a href="#Creating_Web_Service__MyService_">Creating
-Web Service (Echo service)</a></li>
-
-
- <li><a href="#How_to_write_the_Web_Service_">How
-to write the Web Service?</a>
-
+ <li><a href="#Creating_Web_Service__MyService_">Creating Web
+ Service (Echo service)</a></li>
+ <li><a href="#How_to_write_the_Web_Service_">How to write the Web
+ Service?</a>
<ul>
-
-
- <li><a href="#Step1">Step1 :Write the
-echo_skeleton.c file implementing the axis2_svc_skeleton.h</a></li>
-
-
- <li><a href="#Step2">Step2 :Now we can
-write the echo service in a file echo.c</a></li>
-
-
- <li><a href="#Step3">Step3 :Write the
-services.xml file</a></li>
-
-
- <li><a href="#Step4">Step4 :Create the
-WebService Folder </a></li>
-
-
- <li><a href="#Step5">Step5 :Archive
-based deployment model</a></li>
-
-
-
+ <li><a href="#Step1">Step1 :Write the echo_skeleton.c file
+ implementing the axis2_svc_skeleton.h</a></li>
+ <li><a href="#Step2">Step2 :Now we can write the echo service
+ in a file echo.c</a></li>
+ <li><a href="#Step3">Step3 :Write the services.xml file</a></li>
+ <li><a href="#Step4">Step4 :Create the Web Service
+ Folder</a></li>
+ <li><a href="#Step5">Step5 :Archive based deployment
+ model</a></li>
</ul>
-
-
</li>
-
-
-
</ul>
-
-
</li>
-
-
- <li><a href="#Writing_Web_Services_Using_Code_Generator">Writing
-Web Services Skeleton Using Code Generator</a>
-
+ <li><a href="#Writing_Web_Services_Using_Code_Generator">Writing Web
+ Services Skeleton Using Code Generator</a>
<ul>
-
-
- <li><a href="#WSDL2Code_tool">WSDL2Code
-tool</a></li>
-
-
- <li><a href="#Implement_the_Business_Logic">Implement
-the Business Logic</a></li>
-
-
+ <li><a href="#WSDL2Code_tool">WSDL2Code tool</a></li>
+ <li><a href="#Implement_the_Business_Logic">Implement the Business
+ Logic</a></li>
<li><a href="#echoString">echoString</a></li>
-
-
<li><a href="#echoStringArray">echoStringArray</a></li>
-
-
<li><a href="#echoStruct">echoStruct</a></li>
-
-
<li><a href="#services_xml">services.xml</a></li>
-
-
-
</ul>
-
-
</li>
-
-
<li><a href="#deploy">Deploy the Web Service</a></li>
-
-
-
</ul>
-
-
</li>
-
-
- <li>
-
- <p><a href="#Web_Service_Clients_Using_Axis2">Web
-Service Clients Using Axis2/C</a></p>
-
-
-
+ <li><p><a href="#Web_Service_Clients_Using_Axis2">Web Service Clients Using
+ Axis2/C</a></p>
<ul>
-
-
- <li><a href="#Writing_Web_Service_Clients_using_Axis2%27s_Primary_APIs">Writing
-Web Service Clients Using Axis2's Primary APIs</a>
-
+ <li><a
+ href="#Writing_Web_Service_Clients_using_Axis2%27s_Primary_APIs">Writing
+ Web Service Clients Using Axis2's Primary APIs</a>
<ul>
-
-
- <li><a href="#EchoBlockingClient">echo_blocking
-Client</a></li>
-
-
+ <li><a href="#EchoBlockingClient">echo_blocking Client</a></li>
<li><a href="#EchoNonBlockingClient">echo_non_blocking
-Client</a></li>
-
-
+ Client</a></li>
<li><a href="#EchoNonBlockingDualClient">echo_non_blocking_dual
-Client</a></li>
-
-
+ Client</a></li>
<li><a href="#EchoBlockingDualClient">echo_blocking_dual
-Client</a></li>
-
-
-
+ Client</a></li>
</ul>
-
-
</li>
-
-
- <li><a href="#Writing_Web_Clients_Using_Code_Generator">Writing
-Web Service Clients using Code Generation with Data Binding Support</a>
-
+ <li><a href="#Writing_Web_Clients_Using_Code_Generator">Writing Web
+ Service Clients using Code Generation with Data Binding Support</a>
<ul>
-
-
- <li><a href="#Codegenerator_Client_echoString">Client
-for echoString operation</a></li>
-
-
- <li><a href="#Codegenerator_Client_echoStringArray">Client
-for echoStringArray operation</a></li>
-
-
- <li><a href="#Codegenerator_Client_echoStruct">Client
-for echoStruct operation</a></li>
-
-
-
+ <li><a href="#Codegenerator_Client_echoString">Client for
+ echoString operation</a></li>
+ <li><a href="#Codegenerator_Client_echoStringArray">Client for
+ echoStringArray operation</a></li>
+ <li><a href="#Codegenerator_Client_echoStruct">Client for
+ echoStruct operation</a></li>
</ul>
-
-
</li>
-
-
-
</ul>
-
-
</li>
-
-
- <li>
-
- <p><a href="#Providing_security_using_Rampart">Providing
-security using Rampart/C</a></p>
-
-
-
+ <li><p><a href="#Providing_security_using_Rampart">Providing security using
+ Rampart/C</a></p>
<ul>
-
-
- <li><a href="#Engaging_rampart_module">Engaging
-rampart module</a> </li>
-
-
+ <li><a href="#Engaging_rampart_module">Engaging rampart module</a></li>
<li><a href="#Semantics_of_parameters_specified_in_axis2_xml">Semantics
-of parameters specified in axis2.xml</a> </li>
-
-
- <li><a href="#Writing_own_password_callback_module">Writing
-own password callback module</a> </li>
-
-
- <li><a href="#Adding_security_parameters_dynamically">Adding
-security parameters dynamically</a> </li>
-
-
-
+ of parameters specified in axis2.xml</a></li>
+ <li><a href="#Writing_own_password_callback_module">Writing own
+ password callback module</a></li>
+ <li><a href="#Adding_security_parameters_dynamically">Adding security
+ parameters dynamically</a></li>
</ul>
-
-
</li>
-
-
</ul>
-
<h2><a id="Introduction">Introduction</a></h2>
-
-<p>Welcome to Axis2/C, the Apache Axis2 implemented in C. This
-User's Guide
-will help you to understand what Axis2/C has to offer and how to get
-started
+<p>Welcome to Axis2/C, the Apache Axis2 implemented in C. This User's Guide
+will help you to understand what Axis2/C has to offer and how to get started
with it.</p>
-
<h3><a id="What_is_Axis2_">What is Axis2/C?</a></h3>
+<p>Axis2/C is an effort to implement the <a
+href="http://ws.apache.org/axis2/1_0/Axis2ArchitectureGuide.html">Axis2
+architecture</a> in C programming language. For more information on the
+architecture <a href="architecture_notes.html">C Specific Architectural
+Notes</a> are also available.</p>
-<p>Axis2/C is an effort to implement the Axis2 architecture in C
-programming
-language.</p>
-
-
-<p>After months of continued discussion and coding in this
-direction, Axis2/C
+<p>After months of continued discussion and coding in this direction, Axis2/C
now delivers the following key features:</p>
-
-
<ul>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>Speed</strong>
-- Axis2/C uses its own XML object model and StAX (Streaming API for
-XML) parsing to achieve significant speed. In addition to that, Axis2/C
-is inherently benefited by the speed of its implementation language,
-namely C, compared to the Java implementation.</p>
-
-
- </li>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>Low
-memory foot print</strong>- Axis2 architecture was designed
-ground-up keeping the low memory foot print in mind. Axis2/C strives to
-achieve the same with a well designed memory management strategy.</p>
-
-
- </li>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>AXIOM/C</strong>
-Axis2/C comes with its own light-weight object model for XML, AXIOM/C
-which is the C implementation of <a href="http://ws.apache.org/commons/axiom/OMTutorial.html">AXIOM</a>.</p>
-
-
- </li>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>MEP
-Support</strong> - Support Message Exchange Patterns (MEP s)</p>
-
-
- </li>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>Flexibility</strong>
-- The Axis2/C architecture gives the developer complete freedom to
-insert extensions into the engine (using modules and handlers) for
-custom SOAP header processing.</p>
-
-
- </li>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>Transport
-Framework</strong> - We have a clean and simple abstraction for
-integrating and using transports and the core of the engine is
-completely transport-independent.</p>
-
-
- </li>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><strong>Composition
-and Extensibility</strong> - Modules and phases improve support
-for composability and extensibility. Modules supports composability and
-is able to add support for new WS-* specifications in a simple and
-clean manner. They are however not hot deployable as they change the
-overall behavior of the system.</p>
-
-
+ <li><p style="margin-bottom: 0in;"><strong>Speed</strong> - Axis2/C uses
+ its own XML object model and StAX (Streaming API for XML) parsing to
+ achieve significant speed. In addition to that, Axis2/C is inherently
+ benefited by the speed of its implementation language, namely C, compared
+ to the Java implementation.</p>
+ </li>
+ <li><p style="margin-bottom: 0in;"><strong>Low memory foot print</strong>-
+ Axis2 architecture was designed ground-up keeping the low memory foot
+ print in mind. Axis2/C strives to achieve the same with a well designed
+ memory management strategy.</p>
+ </li>
+ <li><p style="margin-bottom: 0in;"><strong>AXIOM/C</strong>- Axis2/C comes
+ with its own light-weight object model for XML, AXIOM/C which is the C
+ implementation of <a
+ href="http://ws.apache.org/commons/axiom/OMTutorial.html">AXIOM</a>.</p>
+ </li>
+ <li><p style="margin-bottom: 0in;"><strong>MEP Support</strong> - Support
+ Message Exchange Patterns (MEPs)</p>
+ </li>
+ <li><p style="margin-bottom: 0in;"><strong>Flexibility</strong> - The
+ Axis2/C architecture gives the developer complete freedom to insert
+ extensions into the engine (using modules and handlers) for custom SOAP
+ header processing.</p>
+ </li>
+ <li><p style="margin-bottom: 0in;"><strong>Transport Framework</strong> -
+ We have a clean and simple abstraction for integrating and using
+ transports, and the core of the engine is completely
+ transport-independent.</p>
+ </li>
+ <li><p style="margin-bottom: 0in;"><strong>Composition and
+ Extensibility</strong> - Modules and phases improve support for
+ composability and extensibility. Modules supports composability and is
+ able to add support for new WS-* specifications in a simple and clean
+ manner. They are however, not hot deployable as they change the overall
+ behavior of the system.</p>
</li>
-
-
</ul>
-
-<p></p>
-
-
-<p>Axis2/C team is working hard to continuously improve the
-implementation.
-Please note that this is an open-source effort. If you feel you have
-some
-time to spare, please get involved and lend us a hand! The Axis2/C
-developer
+<p>Axis2/C team is working hard to continuously improve the implementation.
+Please note that this is an open-source effort. If you feel you have some
+time to spare, please get involved and lend us a hand! The Axis2/C developer
community welcomes your participation and contributions.</p>
-
-<p>Let us know what you think! Please send your feedback on
-Axis2/C to "<a href="mailto:axis-user@ws.apache.org">axis-c-user@ws.apache.org</a>"
-and
+<p>Let us know what you think! Please send your feedback on Axis2/C to "<a
+href="mailto:axis-user@ws.apache.org">axis-c-user@ws.apache.org</a>" and
please remember to prefix the subject of the mail with [Axis2].</p>
+<p>The following sections will guide you through on how to write Web service
+clients and services.</p>
-<p>The following sections will guide through how to write web
-service clients
-and services.</p>
-
-
-
-<h2>Web Services Using Axis2/C</h2>
+<h2><a name="Web_Services_Using_Axis2">Web Services Using Axis2/C</a></h2>
+<p>Before starting, please make sure that you have installed Axis2/C
+correctly and check whether you can run the axis2_http_server located in
+AXIS2C_HOME/bin (See <a href="installationguide.html">Installation Guide</a>
+for details).</p>
-<p>Before starting, please make sure that you have installed
-Axis2/C
-correctly and check whether you can run the axis2_http_server located
-in
-AXIS2C_HOME/bin . (See <a href="installationguide.html">Installation
-Guide</a>).</p>
+<h3><a name="Writing_Web_Services_Using_Axis2_C">Writing Web Services Using Axis2/C</a></h3>
-
-
-<h3>Writing Web Services Using Axis2/C</h3>
-
-
-<h4><a id="Creating_Web_Service__MyService_">Creating
-Web Service (Echo
+<h4><a id="Creating_Web_Service__MyService_">Creating Web Service (Echo
service)</a></h4>
+<p>First let's see how we can write a simple Web Service (echo service) using
+Axis2/C's primary interfaces and how to deploy it. For this purpose we will
+create a Web Service with one operation as follows.</p>
+<pre><br />axiom_node_t* axis2_echo_echo(axiom_node_t *echo_node){}<br /> </pre>
-<p>First let's see how we can write a simple Web Service (echo
-service) using
-Axis2/C's primary interfaces and deploy it. For this purpose we will
-create a
-Web Service with one operation as follows.</p>
-
-
-<pre><br>axiom_node_t* axis2_echo_echo(axiom_node_t *echo_node){}<br> </pre>
-
-
-<p>You can have a peek at the complete source code for this
-example echo
-service located in the "AXIS2C_HOME/samples/server/echo" directory .</p>
+<p>You can have a peek at the complete source code for this example echo
+service located in the "AXIS2C_HOME/samples/server/echo" directory.</p>
-
-<h4><a id="How_to_write_the_Web_Service_">How to
-write the Web
+<h4><a id="How_to_write_the_Web_Service_">How to write the Web
Service?</a></h4>
-
-<p>Writing a new Web Service with Axis2/C involve four steps.</p>
-
-
-<p>(eg . echo service )</p>
-
-
+<p>Writing a new Web Service with Axis2/C involve four steps. Let's take echo
+service as our example.</p>
<ol>
-
-
- <li>
-
- <p style="margin-bottom: 0in;">Write a echo_skeleton.c
-file which implements the API given in axis2_svc_skeleton.h header file.</p>
-
-
+ <li><p style="margin-bottom: 0in;">Write a echo_skeleton.c file which
+ implements the API given in axis2_svc_skeleton.h header file.</p>
</li>
-
-
- <li>Write the service implementation source file (in this case
-echo.c service) which implements the actual business logic.</li>
-
-
- <li>Write a services.xml file to explain the Web Service.</li>
-
-
- <li>Create a folder with the service name under
-AXIS2C_HOME/services and put the compiled service ( .dll or .so file)
-for the Web Service and services.xml file in to that folder</li>
-
-
+ <li>Write the service implementation source file (in this case echo.c
+ service) which implements the actual business logic.</li>
+ <li>Write a services.xml file to explain the Web service.</li>
+ <li>Create a folder with the service name under AXIS2C_HOME/services and
+ put the compiled service ( .dll or .so file) for the Web service and
+ services.xml file in to that folder</li>
</ol>
-
-
-<p></p>
-
-
+<a name="Step1"></a>
<h4>Step1 :Write the echo_skeleton.c file implementing the
axis2_svc_skeleton.h</h4>
-
-<p>axis2_svc_skeleton.h header file has the
-axis2_svc_skeleton_ops_t
-operations struct which defines four function pointers to be
-implemented and
+<p>axis2_svc_skeleton.h header file has the axis2_svc_skeleton_ops_t
+operations struct which defines four function pointers to be implemented and
assigned by a service skeleton.</p>
+<p>They are:</p>
+<pre class="code">int (AXIS2_CALL * init) (axis2_svc_skeleton_t *svc_skeleton,<br /> const axis2_env_t *env);<br /><br />axiom_node_t * (AXIS2_CALL* invoke)(axis2_svc_skeleton_t *svc_skeli, <br /> const axis2_env_t *env, axiom_node_t *node);<br /><br />axiom_node_t *(AXIS2_CALL* on_fault)(axis2_svc_skeleton_t *svc_skeli,<br /> const axis2_env_t *env, axiom_node_t *node);<br /><br />int (AXIS2_CALL *free)(axis2_svc_skeleton_t *svc_skeli, <br /> const axis2_env_t *env);</pre>
-<p>They are:-</p>
-
-
-<pre class="code">int (AXIS2_CALL * init) (axis2_svc_skeleton_t *svc_skeleton,<br> const axis2_env_t *env);<br><br>axiom_node_t * (AXIS2_CALL* invoke)(axis2_svc_skeleton_t *svc_skeli, <br> const axis2_env_t *env, axiom_node_t *node);<br><br>axiom_node_t *(AXIS2_CALL* on_fault)(axis2_svc_skeleton_t *svc_skeli,<br> const axis2_env_t *env, axiom_node_t *node);<br><br>int (AXIS2_CALL *free)(axis2_svc_skeleton_t *svc_skeli, <br> const axis2_env_t *env);</pre>
-
-
-<p></p>
-
-
-<p>Lets implement the above functions for echo service.</p>
+<p>Let's implement the above functions for echo service.</p>
+<p><i><code>/* Initialize the service */</code></i><br />
+<code>int AXIS2_CALL</code><br />
+<code>echo_init(axis2_svc_skeleton_t *svc_skeleton,</code><br />
+<code> const axis2_env_t *env)</code><br />
+<code>{</code><br />
+<code> svc_skeleton->func_array = axis2_array_list_create(env, 0);</code><br
+/>
+<code> </code><i><code>/* Add the implemented operation names of the service to </code><br
+/>
+<code> * the array list of functions </code><br />
+<code> */</code></i><br />
+<code> AXIS2_ARRAY_LIST_ADD(svc_skeleton->func_array, env, "echoString");</code><br
+/>
+<code> </code><i><code>/* Any initialization stuff of echo service should go here */</code></i><br
+/>
+<code> </code><b><code>return</code></b><code> AXIS2_SUCCESS;</code><br />
+<code>}</code><br />
+<br />
+<i><code>/*</code><br />
+<code> * This method invokes the right service method </code><br />
+<code> */</code></i><br />
+<code>axiom_node_t* AXIS2_CALL</code><br />
+<code>echo_invoke(axis2_svc_skeleton_t *svc_skeleton,</code><br />
+<code> const axis2_env_t *env,</code><br />
+<code> axiom_node_t *node)</code><br />
+<code>{</code><br />
+<code> </code><i><code>/* Invoke the business logic.</code><br />
+<code> * Depending on the function name invoke the correct impl method.</code><br
+/>
+<code> * We have only echo in this sample, hence invoke echo method.</code><br
+/>
+<code> * To see how to deal with multiple impl methods, have a look at the</code><br
+/>
+<code> * math sample.</code><br />
+<code> */</code></i><br />
+<code> </code><b><code>return</code></b><code> axis2_echo_echo(env, node);</code><br
+/>
+<code>}</code><br />
+<br />
+<i><code>/* On fault, handle the fault */</code></i><br />
+<code>axiom_node_t* AXIS2_CALL</code><br />
+<code>echo_on_fault(axis2_svc_skeleton_t *svc_skeli, </code><br />
+<code> const axis2_env_t *env, axiom_node_t *node)</code><br />
+<code>{</code><br />
+<code> </code><i><code>/* Here we are just setting a simple error message inside an element </code><br
+/>
+<code> * called 'EchoServiceError' </code><br />
+<code> */</code></i><br />
+<code> axiom_node_t *error_node = NULL;</code><br />
+<code> axiom_node_t* text_node = NULL;</code><br />
+<code> axiom_element_t *error_ele = NULL;</code><br />
+<code> error_ele = axiom_element_create(env, node, "EchoServiceError", NULL, </code><br
+/>
+<code> &error_node);</code><br />
+<code> AXIOM_ELEMENT_SET_TEXT(error_ele, env, "Echo service failed ", </code><br
+/>
+<code> text_node);</code><br />
+<code> </code><b><code>return</code></b><code> error_node;</code><br />
+<code>}</code><br />
+<br />
+<i><code>/* Free the resources used */</code></i><br />
+<code>int AXIS2_CALL</code><br />
+<code>echo_free(axis2_svc_skeleton_t *svc_skeleton,</code><br />
+<code> const axis2_env_t *env)</code><br />
+<code>{</code><br />
+<code> </code><i><code>/* Free the function array */</code></i><br />
+<code> </code><b><code>if</code></b><code>(svc_skeleton->func_array)</code><br
+/>
+<code> {</code><br />
+<code> AXIS2_ARRAY_LIST_FREE(svc_skeleton->func_array, env);</code><br
+/>
+<code> svc_skeleton->func_array = NULL;</code><br />
+<code> }</code><br />
+<code> </code><br />
+<code> </code><i><code>/* Free the function array */</code></i><br />
+<code> </code><b><code>if</code></b><code>(svc_skeleton->ops)</code><br
+/>
+<code> {</code><br />
+<code> AXIS2_FREE(env->allocator, svc_skeleton->ops);</code><br
+/>
+<code> svc_skeleton->ops = NULL;</code><br />
+<code> }</code><br />
+<code> </code><br />
+<code> </code><i><code>/* Free the service skeleton */</code></i><br />
+<code> </code><b><code>if</code></b><code>(svc_skeleton)</code><br />
+<code> {</code><br />
+<code> AXIS2_FREE(env->allocator, svc_skeleton);</code><br />
+<code> svc_skeleton = NULL;</code><br />
+<code> }</code><br />
+<br />
+<code> </code><b><code>return</code></b><code> AXIS2_SUCCESS; </code><br />
+<code>}</code><br />
+</p>
<p></p>
+<p>Now we can write the <code>create</code> function of the
+echo_service_skeleton as follows:</p>
-<p><i><code>/* Initialize the service */</code></i><br>
-
-
-<code>int AXIS2_CALL</code><br>
-
-
-<code>echo_init(axis2_svc_skeleton_t *svc_skeleton,</code><br>
+<p><i><code>/*Create function */</code><br />
+</i><code>axis2_svc_skeleton_t *</code><br />
+<code>axis2_echo_create(const axis2_env_t *env)</code><br />
+<code>{</code><br />
+<code> axis2_svc_skeleton_t *svc_skeleton = NULL;</code><br />
+<code> </code><i><code>/* Allocate memory for the structs */</code></i><br
+/>
+<code> svc_skeleton = AXIS2_MALLOC(env->allocator, </code><br />
+<code> </code><b><code>sizeof</code></b><code>(axis2_svc_skeleton_t));</code><br
+/>
+<br />
+<code> svc_skeleton->ops = AXIS2_MALLOC(</code><br />
+<code> env->allocator, </code><b><code>sizeof</code></b><code>(axis2_svc_skeleton_ops_t));</code><br
+/>
+<br />
+<code> </code><i><code>/* Assign function pointers */</code></i><br />
+<code> svc_skeleton->ops->free = echo_free;</code><br />
+<code> svc_skeleton->ops->init = echo_init;</code><br />
+<code> svc_skeleton->ops->invoke = echo_invoke;</code><br />
+<code> svc_skeleton->ops->on_fault = echo_on_fault;</code><br />
+<br />
+<code> </code><b><code>return</code></b><code> svc_skeleton;</code><br />
+<code>}</code></p>
+<p>In addition to the above functions, every service must have the following
+two functions with exactly the same function signature as in xxx_skeleton.c
+file.</p>
-<code> const
-axis2_env_t *env)</code><br>
+<p><code>AXIS2_EXPORT int </code><br />
+<code>axis2_get_instance(axis2_svc_skeleton_t **inst,</code><br />
+<code> const axis2_env_t *env)</code><br />
+<code>{</code><br />
+<code> *inst = axis2_echo_create(env);</code><br />
+<code> </code><b><code>if</code></b><code>(!(*inst))</code><br />
+<code> {</code><br />
+<code> </code><b><code>return</code></b><code> AXIS2_FAILURE;</code><br
+/>
+<code> }</code><br />
+<code> </code><b><code>return</code></b><code> AXIS2_SUCCESS;</code><br />
+<code>}</code><br />
+<br />
+<code>AXIS2_EXPORT int </code><br />
+<code>axis2_remove_instance(axis2_svc_skeleton_t *inst,</code><br />
+<code> const axis2_env_t *env)</code><br />
+<code>{</code><br />
+<code> axis2_status_t status = AXIS2_FAILURE;</code><br />
+<code> </code><b><code>if</code></b><code> (inst)</code><br />
+<code> {</code><br />
+<code> status = AXIS2_SVC_SKELETON_FREE(inst, env);</code><br />
+<code> }</code><br />
+<code> </code><b><code>return</code></b><code> status;</code><br />
+}<br />
+</p>
+<p></p>
-<code>{</code><br>
+<p>Axis2/C engine can load the service dll. However, it needs to know which
+method to call. Since C does not have reflection, we need to have some dll
+exposed functions known to Axis2/C engine.
+<b><code>axis2_get_instance</code></b> and
+<b><code>axis2_remove_instance</code></b> are the two functions that need to
+be exposed from a service dll (or any other dll of Axis2/C engine). Axis2/C
+engine calls <code>axis2_get_instance</code> method, which creates a new
+service instance, and cast the return pointer to
+<code>axis2_svc_skeleton</code> interface. Then the interface methods can be
+called by Axis2/C engine.</p>
+<a name="Step2"></a>
+<h4>Step2 : Now we can write the echo service in a file echo.c</h4>
+<p><code>axiom_node_t *</code><br />
+<code>axis2_echo_echo (const axis2_env_t *env, axiom_node_t *node)</code><br
+/>
+<code>{</code><br />
+<code> axiom_node_t *text_parent_node = NULL;</code><br />
+<code> axiom_node_t *text_node = NULL;</code><br />
+<code> axiom_node_t *ret_node = NULL;</code><br />
+<br />
+<code> AXIS2_ENV_CHECK(env, NULL);</code><br />
+<code> </code><br />
+<code> </code><i><code>/* Expected request format is :-</code><br />
+<code> * <ns1:echoString xmlns:ns1="http://localhost:9090/axis2/services/echo"></code><br
+/>
+<code> * <text>echo5</text></code><br />
+<code> * </ns1:echoString></code><br />
+<code> */</code></i><br />
+<code> </code><b><code>if</code></b><code> (!node) </code><i><code>/* 'echoString' node */</code></i><br
+/>
+<code> {</code><br />
+<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INPUT_OM_NODE_NULL, AXIS2_FAILURE);</code><br
+/>
+<code> printf("Echo client ERROR: input parameter NULL\n");</code><br
+/>
+<code> </code><b><code>return</code></b><code> NULL;</code><br />
+<code> }</code><br />
+<br />
+<code> text_parent_node = AXIOM_NODE_GET_FIRST_CHILD(node, env);</code><br
+/>
+<code> </code><b><code>if</code></b><code> (!text_parent_node) </code><i><code>/* 'text' node */</code></i><br
+/>
+<code> {</code><br />
+<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);</code><br
+/>
+<code> printf("Echo client ERROR: invalid XML in request\n");</code><br
+/>
+<code> </code><b><code>return</code></b><code> NULL;</code><br />
+<code> }</code><br />
+<code> </code><br />
+<code> text_node = AXIOM_NODE_GET_FIRST_CHILD(text_parent_node, env);</code><br
+/>
+<code> </code><b><code>if</code></b><code> (!text_node) </code><i><code>/* actual text to echo */</code></i><br
+/>
+<code> {</code><br />
+<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);</code><br
+/>
+<code> printf("Echo client ERROR: invalid XML in request\n");</code><br
+/>
+<code> </code><b><code>return</code></b><code> NULL;</code><br />
+<code> }</code><br />
+<code> </code><br />
+<code> </code><b><code>if</code></b><code> (AXIOM_NODE_GET_NODE_TYPE(text_node, env) == AXIOM_TEXT)</code><br
+/>
+<code> {</code><br />
+<code> axiom_text_t *text = (axiom_text_t *)AXIOM_NODE_GET_DATA_ELEMENT(text_node, env);</code><br
+/>
+<code> </code><b><code>if</code></b><code>( text && AXIOM_TEXT_GET_VALUE(text , env))</code><br
+/>
+<code> {</code><br />
+<code> axis2_char_t *text_str = AXIOM_TEXT_GET_VALUE(text, env);</code><br
+/>
+<code> printf("Echoing text value %s \n", text_str);</code><br />
+<code> ret_node = build_om_programatically(env, text_str);</code><br
+/>
+<code> }</code><br />
+<code> }</code><br />
+<code> </code><b><code>else</code></b><br />
+<code> {</code><br />
+<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);</code><br
+/>
+<code> printf("Echo client ERROR: invalid XML in request\n");</code><br
+/>
+<code> </code><b><code>return</code></b><code> NULL;</code><br />
+<code> }</code><br />
+<code> </code><br />
+<code> </code><b><code>return</code></b><code> ret_node;</code><br />
+<code>}</code><br />
+<br />
+<i><code>/* Builds the response content */</code></i><br />
+<code>axiom_node_t *</code><br />
+<code>build_om_programatically(const
+axis2_env_t *env, axis2_char_t *text)</code><br />
+<code>{</code><br />
+<code> axiom_node_t *echo_om_node = NULL;</code><br />
+<code> axiom_element_t* echo_om_ele = NULL;</code><br />
+<code> axiom_node_t* text_om_node = NULL;</code><br />
+<code> axiom_element_t * text_om_ele = NULL;</code><br />
+<code> axiom_namespace_t *ns1 = NULL;</code><br />
+<code> </code><br />
+<code> ns1 = axiom_namespace_create (env, "http://localhost:9090/axis2/services/echo", "ns1");</code><br
+/>
+<br />
+<code> echo_om_ele = axiom_element_create(env, NULL, "echoString", ns1, &echo_om_node);</code><br
+/>
+<code> </code><br />
+<code> text_om_ele = axiom_element_create(env, echo_om_node, "text", NULL, &text_om_node);</code><br
+/>
+<br />
+<code> AXIOM_ELEMENT_SET_TEXT(text_om_ele, env, text, text_om_node);</code><br
+/>
+<code> </code><br />
+<code> </code><b><code>return</code></b><code> echo_om_node;</code><br />
+<code>}</code><br />
+</p>
+<a name="Step3"></a>
+<h4>Step3 :Write the services.xml file</h4>
-<code> svc_skeleton->func_array = axis2_array_list_create(env, 0);</code><br>
+<p>Axis2/C uses "services.xml" file to keep configurations of a Web service.
+Each Web service deployed in Axis2/C needs a "services.xml" file containing
+the configurations. Note that services.xml has the same semantics as Axis2
+Java's services.xml file. Only difference is that instead of giving package
+qualified class name, we use the dll name for class attributes.</p>
+
+<p>"services.xml" for echo will be as follows:</p>
+<pre class="code"><service name="echo"><br /> <parameter name="ServiceClass" locked="xsd:false">echo</parameter><br /> <description><br /> This is a echo service<br /> </description><br /><br /> <operation name="echoString"><br /> <parameter name="wsamapping"><br /> http://localhost:9090/axis2/services/echo/echoString<br /> </parameter><br /> </operation><br /></service></pre>
+
+<p>Name of the service will be the name of the folder with the shared library
+and the services.xml. In the case of this example we will have a folder named
+"echo" in which we have the echo.dll (or libecho.so on Linux platform) and
+services.xml file.</p>
+<p>You can write a services.xml file to include a group of services instead
+of a single service. This makes management and deployment of a set of related
+services very easy. At runtime you can share information between these
+services within a single interaction using the <code>axis2_svc_grp_ctx</code>
+(Service Group Context ). If you hope to use this functionality, the
+services.xml file should have following format:<br />
+</p>
+<pre class="code"><serviceGroup><br /> <service name="Service1"><br /> <!-- details for Service1 --><br /> </service><br /> <service name="Service2"><br /> <!-- details for Service2 --><br /> </service><br /> <module ref="ModuleName" /><br /> <parameter name="serviceGroupParam1" locked="false">value 1</parameter><br /></serviceGroup></pre>
-<code> </code><i><code>/* Add the implemented operation names of the service to </code><br>
+<p>Note : name of the service is a compulsory attribute</p>
+<a name="Step4"></a>
+<h4>Step4 :Create the Web service folder in services folder of the
+repository.</h4>
+<p>In Axis2/C , it is required to create a folder with the corresponding
+service/service group name which will contain the shared library (compiled
+service) and the services.xml file which describes the Web service. So for
+this example, we will have to create a folder named "echo", which contains
+the services.xml file and echo dll.</p>
+<a name="Step5"></a>
+<h4>Step5 :Archive Based Deployment Model</h4>
+
+<p>Axis2 uses ".aar" (Axis Archive) file as the deployment package for the
+Web services. Therefore, for echo service we will use "echo.aar". Note that
+the name of the service will be the name of the archive file. To create
+"echo.aar" user can create a zip file containing echo.so and services.xml and
+rename the zip extension to aar. Then Axis2 understands it as a service
+archive.</p>
-<code> * the array list of functions </code><br>
+<h3><a name="Writing_Web_Services_Using_Code_Generator">Writing Web Services Skeleton Using Code Generator</a></h3>
+<h4><a id="WSDL2Code_tool">WSDL2Code tool</a></h4>
-<code> */</code></i><br>
+<p>Axis2/Java WSDL2Code tool supports generation of Axis2/C stub and
+skeleton. <a
+href="http://svn.apache.org/viewvc/webservices/axis2/trunk/java">Axis2/Java
+SVN</a> revision 414253 and later versions provides this facility. A basic
+guide for the tool can be found <a
+href="http://ws.apache.org/axis2/1_0/userguide2.html#Writing_Web_Services_by_Code_Generating_Skeleton">here</a></p>
+
+<p>We will run the tool with the following parameters and generate the
+skeleton and the other required files to support ADB (Axis Data Binding). In
+order to run the tool, <span style="font-weight: bold;">set all the .jar
+library files in the Axis2/Java to the classpath</span>. To generate code
+with no data binding support, just replace -d adb -u with -d none</p>
+<pre><br />java -Dorg.apache.adb.properties=/org/apache/axis2/schema/c-schema-compile.properties org.apache.axis2.wsdl.WSDL2Code <br /> -uri interoptestdoclitparameters.wsdl -ss -sd -d adb -u<br /> </pre>
+
+<p>If you need an XML in/out programming model, you can just ignore the data
+binding support by setting following parameters. Give "<code>-l c</code>"
+option to enable C language code generation.</p>
+<pre><br />java org.apache.axis2.wsdl.WSDL2Code -uri interoptestdoclitparameters.wsdl -ss -sd -d none -l c<br /> </pre>
+<p>The WSDL <code>interoptestdoclitparameters.wsdl</code> can be found in
+<axis2_src_dir>/test/resources directory. This is used to generate stub
+and skeleton code throughout this User's Guide.</p>
-<code> AXIS2_ARRAY_LIST_ADD(svc_skeleton->func_array, env, "echoString");</code><br>
+<h4><a id="Implement_the_Business_Logic">Implement the Business Logic</a></h4>
+Locate the skeleton source file from the generated files:
+"<code>axis2_WSDLInteropTestDocLitService.c</code>". You can go through the
+rest of the guide to add the business logic to the following operations in
+the WSDL.
+<ul>
+ <li>echoString - Operation that echoes a String value</li>
+ <li>echoStringArray - Operation that accept string array as the input and
+ echoes them back</li>
+ <li>echoStruct - Operation that accept a Struct as the input and echoes
+ them back</li>
+</ul>
+<p>Complete skeleton source file for the above operations can be found under
+<axis2_src_dir>/samples/codegen/server/interop_doc2 directory with the
+name "<code>axis2_WSDLInteropTestDocLitService.c</code>".</p>
-<code> </code><i><code>/* Any initialization stuff of echo service should go here */</code></i><br>
+<h4><a id="echoString">echoString</a></h4>
+<p>If you generate the code with data binding support, you will find the
+following code segment in the
+"<code>axis2_WSDLInteropTestDocLitService.c</code>". Fill the business logic
+inside this function as shown below:</p>
+<pre>axis2_echoStringResponse_t*<br />axis2_WSDLInteropTestDocLitService_echoString<br /> (const axis2_env_t* env ,axis2_echoString_t* param6 )<br />{<br /> /* Todo fill this with the necessary business logic */<br />}</pre>
+
+<p>Once filled with the business logic, it will be as follows. The code is
+simple and the inline comments provide explanation.</p>
+<pre>axis2_echoStringResponse_t*<br />axis2_WSDLInteropTestDocLitService_echoString<br /> (const axis2_env_t* env ,axis2_echoString_t* param6 )<br />{<br /> axis2_echoString_t* echo_in = param6;<br /> axis2_echoStringResponse_t* echo_out = NULL;<br /><br /> char* echo_string = NULL;<br /> <br /> /* retrieve the string input */<br /> echo_string = AXIS2_ECHOSTRING_GET_PARAM0 ( echo_in, env );<br /><br /> /* create the response and set the output string */<br /> echo_out = axis2_echoStringResponse_create ( env );<br /> AXIS2_ECHOSTRUCTRESPONSE_SET_RETURN ( echo_out, env, echo_string );<br /><br /> return echo_out;<br />}</pre>
-<code> </code><b><code>return</code></b><code> AXIS2_SUCCESS;</code><br>
+<h4><a id="echoStringArray">echoStringArray</a></h4>
+<pre>axis2_echoStringArrayResponse_t*<br />axis2_WSDLInteropTestDocLitService_echoStringArray<br /> (const axis2_env_t* env ,axis2_echoStringArray_t* param2 )<br /><br />{<br /> axis2_echoStringArray_t* echo_in = param2;<br /> axis2_echoStringArrayResponse_t* echo_out = NULL;<br /> axis2_ArrayOfstring_literal_t* array_in = NULL;<br /> axis2_ArrayOfstring_literal_t* array_out = NULL;<br /> char ** string_array = NULL;<br /> int string_array_length = 0;<br /> <br /> /* retrieve the array from input*/<br /> array_in = AXIS2_ECHOSTRINGARRAY_GET_PARAM0( echo_in, env);<br /> /* retrieve the string_array and array length */<br /> string_array =<br /> AXIS2_ARRAYOFSTRING_LITERAL_GET_STRING <br /> (array_in, env,&string_array_length );<br /> <br /> /* create the output array and set the string array and length */<br /> array_out = axis2_ArrayOfstring_literal_create ( env );<br /> AXIS2_ARRAYOFSTRING_LITERAL_SET_STRING(<br /> array_out, env, string_array, string_array_length );<br
/> <br /> /* create the response and set the output*/<br /> echo_out = axis2_echoStringArrayResponse_create ( env );<br /> AXIS2_ECHOSTRINGARRAYRESPONSE_SET_RETURN ( echo_out, env , array_out );<br /> <br /> return echo_out;<br /><br />}</pre>
+<h4><a id="echoStruct">echoStruct</a></h4>
+<pre>axis2_echoStructResponse_t*<br />axis2_WSDLInteropTestDocLitService_echoStruct<br /> (const axis2_env_t* env ,axis2_echoStruct_t* param4 )<br /><br />{<br /> axis2_echoStruct_t* echo_in = param4;<br /> axis2_echoStructResponse_t* echo_out = NULL;<br /> axis2_SOAPStruct_t* struct_in = NULL;<br /> axis2_SOAPStruct_t* struct_out = NULL;<br /> <br /> float float_val = 0;<br /> int int_val = 0;<br /> char* string_val = NULL;<br /> <br /> /* retrieve the structure from input */<br /> struct_in = AXIS2_ECHOSTRUCT_GET_PARAM0( echo_in, env);<br /><br /> /* retrieve each value from the structure */ <br /> float_val = AXIS2_SOAPSTRUCT_GET_VARFLOAT ( struct_in, env);<br /> int_val = AXIS2_SOAPSTRUCT_GET_VARINT ( struct_in, env);<br /> string_val = AXIS2_SOAPSTRUCT_GET_VARSTRING ( struct_in, env);<br /> <br /> /* create the output structure and set values */<br /> struct_out = axis2_SOAPStruct_create( env );<br /> AXIS2_SOAPSTRUCT_SET_VARFLOAT ( struct_out, env, float_val );<br /> A
XIS2_SOAPSTRUCT_SET_VARINT ( struct_out, env, int_val );<br /> AXIS2_SOAPSTRUCT_SET_VARSTRING ( struct_out, env, string_val );<br /> <br /> /* create the response and set the output structure*/<br /> echo_out = axis2_echoStructResponse_create ( env );<br /> AXIS2_ECHOSTRUCTRESPONSE_SET_RETURN ( echo_out, env, struct_out );<br /> <br /> return echo_out;<br />}<br /></pre>
-<code>}</code><br>
+<h4><a id="services_xml">services.xml</a></h4>
+Axis2 uses "services.xml" to hold the configurations for a particular Web
+service deployed in the Axis2 engine. When we generate the skeleton using the
+WSDL2Java tool, it will also generate the required services.xml for this Web
+service as well. This is essential to <a href="#deploy">deploy the
+service</a>. Please refer to the '<a href="#Step3">Write the
+services.xml</a>' section in this guide to learn more about services.xml
+<a name="deploy"></a>
+<h3>Deploy the Web Service</h3>
+<p>We simply put our service folder or the ".aar" file to the services
+directory. You need restart the server for the engine to pick this
+service.</p>
-<br>
+<h2><a name="Web_Service_Clients_Using_Axis2">Web Service Clients Using Axis2/C</a></h2>
+<p>Now let's see how we can write a Web service client to consume a Web
+service.</p>
-<i><code>/*</code><br>
+<p>Web services can be used to provide wide range of functionality to the
+users ranging from simple, less time consuming operations such as
+"getStockQuote" to time consuming business services. When we utilize (invoke
+using client applications) these Web services, we cannot use some simple
+generic invocation paradigm that suits all the timing complexities involved
+in the service operations. For example, if we use a single transport channel
+(such as HTTP) to invoke a Web service with an IN-OUT operation that take
+long time to complete, then most of the time we may end up with "connection
+time outs". On the other hand, if there are simultaneous service invocations
+that we need to perform from a single client application, then the use of a
+"blocking" client API will degrade the performance of the client application.
+Similarly, there are various other consequences such as One-Way transports
+that come in to play when we need them. Let's try to analyze some common
+service invocation paradigms.</p>
+<p>Many Web service engines provide the users with a Blocking and
+Non-Blocking client APIs.</p>
+<ul>
+ <li><p style="margin-bottom: 0in;"><b>Blocking API</b> -Once the service
+ invocation is called, the client application hangs and only gets control
+ back when the operation completes, after which client receives a response
+ or a fault. This is the simplest way of invoking Web services and it also
+ suits many business situations.</p>
+ </li>
+ <li><b>Non-Blocking API</b>- This is a callback or polling based API.
+ Hence, once a service invocation is called, the client application
+ immediately gets the control back and the response is retrieved using the
+ callback object provided. This approach provides the flexibility to the
+ client application to invoke several Web services simultaneously without
+ blocking the operation already invoked.</li>
+</ul>
-<code> * This method invokes the right service method </code><br>
-
-
-<code> */</code></i><br>
-
-
-<code>axiom_node_t* AXIS2_CALL</code><br>
-
-
-<code>echo_invoke(axis2_svc_skeleton_t *svc_skeleton,</code><br>
-
-
-<code> const
-axis2_env_t *env,</code><br>
-
-
-<code> axiom_node_t *node)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> </code><i><code>/* Invoke the business logic.</code><br>
-
-
-<code> * Depending on the function name invoke the correct impl method.</code><br>
-
-
-<code> * We have only echo in this sample, hence invoke echo method.</code><br>
-
-
-<code> * To see how to deal with multiple impl methods, have a look at the</code><br>
-
-
-<code> * math sample.</code><br>
-
-
-<code> */</code></i><br>
-
-
-<code> </code><b><code>return</code></b><code> axis2_echo_echo(env, node);</code><br>
-
-
-<code>}</code><br>
-
-
-<br>
-
-
-<i><code>/* On fault, handle the fault */</code></i><br>
-
-
-<code>axiom_node_t* AXIS2_CALL</code><br>
-
-
-<code>echo_on_fault(axis2_svc_skeleton_t *svc_skeli, </code><br>
-
-
-<code> const
-axis2_env_t *env, axiom_node_t *node)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> </code><i><code>/* Here we are just setting a simple error message inside an element </code><br>
-
-
-<code> * called 'EchoServiceError' </code><br>
-
-
-<code> */</code></i><br>
-
-
-<code> axiom_node_t *error_node = NULL;</code><br>
-
-
-<code> axiom_node_t* text_node = NULL;</code><br>
-
-
-<code> axiom_element_t *error_ele = NULL;</code><br>
-
-
-<code> error_ele = axiom_element_create(env, node, "EchoServiceError", NULL, </code><br>
-
-
-<code> &error_node);</code><br>
-
-
-<code> AXIOM_ELEMENT_SET_TEXT(error_ele, env, "Echo service failed ", </code><br>
-
-
-<code> text_node);</code><br>
-
-
-<code> </code><b><code>return</code></b><code> error_node;</code><br>
-
-
-<code>}</code><br>
-
-
-<br>
-
-
-<i><code>/* Free the resources used */</code></i><br>
-
-
-<code>int AXIS2_CALL</code><br>
-
-
-<code>echo_free(axis2_svc_skeleton_t *svc_skeleton,</code><br>
-
-
-<code> const
-axis2_env_t *env)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> </code><i><code>/* Free the function array */</code></i><br>
-
-
-<code> </code><b><code>if</code></b><code>(svc_skeleton->func_array)</code><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_ARRAY_LIST_FREE(svc_skeleton->func_array, env);</code><br>
-
-
-<code> svc_skeleton->func_array = NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><br>
-
-
-<code> </code><i><code>/* Free the function array */</code></i><br>
-
-
-<code> </code><b><code>if</code></b><code>(svc_skeleton->ops)</code><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_FREE(env->allocator, svc_skeleton->ops);</code><br>
-
-
-<code> svc_skeleton->ops = NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><br>
-
-
-<code> </code><i><code>/* Free the service skeleton */</code></i><br>
-
-
-<code> </code><b><code>if</code></b><code>(svc_skeleton)</code><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_FREE(env->allocator, svc_skeleton);</code><br>
-
-
-<code> svc_skeleton = NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<br>
-
-
-<code> </code><b><code>return</code></b><code> AXIS2_SUCCESS; </code><br>
-
-
-<code>}</code><br>
-
-
-</p>
-
-
-<p></p>
-
-
-<p>Now we can write the <code>create</code> function
-of the
-echo_service_skeleton as<br>
-
-
-follows.</p>
-
-
-<p></p>
-
-
-<p><i><code>/*Create function */</code><br>
-
-
-</i><code> axis2_svc_skeleton_t *</code><br>
-
-
-<code>axis2_echo_create(const axis2_env_t *env)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> axis2_svc_skeleton_t *svc_skeleton = NULL;</code><br>
-
-
-<code> </code><i><code>/* Allocate memory for the structs */</code></i><br>
-
-
-<code> svc_skeleton = AXIS2_MALLOC(env->allocator, </code><br>
-
-
-<code> </code><b><code>sizeof</code></b><code>(axis2_svc_skeleton_t));</code><br>
-
-
-<br>
-
-
-<code> svc_skeleton->ops = AXIS2_MALLOC(</code><br>
-
-
-<code> env->allocator, </code><b><code>sizeof</code></b><code>(axis2_svc_skeleton_ops_t));</code><br>
-
-
-<br>
-
-
-<code> </code><i><code>/* Assign function pointers */</code></i><br>
-
-
-<code> svc_skeleton->ops->free = echo_free;</code><br>
-
-
-<code> svc_skeleton->ops->init = echo_init;</code><br>
-
-
-<code> svc_skeleton->ops->invoke = echo_invoke;</code><br>
-
-
-<code> svc_skeleton->ops->on_fault = echo_on_fault;</code><br>
-
-
-<br>
-
-
-<code> </code><b><code>return</code></b><code> svc_skeleton;</code><br>
-
-
-<code>}</code></p>
-
-
-<p></p>
-
-
-<p>In addition to the above functions, every service must have
-the following
-two functions with exactly the same function signature as in
-xxx_skeleton.c
-file.</p>
-
-
-<p><br>
-
-
-</p>
-
-
-<p><code>AXIS2_EXPORT int </code><br>
-
-
-<code>axis2_get_instance(axis2_svc_skeleton_t **inst,</code><br>
-
-
-<code> const
-axis2_env_t *env)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> *inst = axis2_echo_create(env);</code><br>
-
-
-<code> </code><b><code>if</code></b><code>(!(*inst))</code><br>
-
-
-<code> {</code><br>
-
-
-<code> </code><b><code>return</code></b><code> AXIS2_FAILURE;</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><b><code>return</code></b><code> AXIS2_SUCCESS;</code><br>
-
-
-<code>}</code><br>
-
-
-<br>
-
-
-<code>AXIS2_EXPORT int </code><br>
-
-
-<code>axis2_remove_instance(axis2_svc_skeleton_t *inst,</code><br>
-
-
-<code> const
-axis2_env_t *env)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> axis2_status_t status = AXIS2_FAILURE;</code><br>
-
-
-<code> </code><b><code>if</code></b><code> (inst)</code><br>
-
-
-<code> {</code><br>
-
-
-<code> status = AXIS2_SVC_SKELETON_FREE(inst, env);</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><b><code>return</code></b><code> status;</code><br>
-
-
-}<br>
-
-
-</p>
-
-
-<p></p>
-
-
-<p>Axis2/C engine can load the service dll, however, it needs to
-know which
-method to call. Since C does not have reflection, we need to have some
-dll
-exposed functions known to Axis2/C engine.
-<b><code>axis2_get_instance</code></b> and
-<b><code>axis2_remove_instance</code></b> are
-the two functions that need to
-be exposed from a service dll (or any other dll of Axis2/C engine).
-Axis2/C
-engine calls <code>axis2_get_instance</code> method, which
-creates a new
-service instance, and cast the return pointer to
-<code>axis2_svc_skeleton</code> interface.Then the
-interface methods can be
-called by Axis2/C engine.</p>
-
-
-<p></p>
-
-
-<h4>Step2 : Now we can write the echo service in a file echo.c</h4>
-
-
-<p><code>axiom_node_t *</code><br>
-
-
-<code>axis2_echo_echo (const
-axis2_env_t *env, axiom_node_t *node)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> axiom_node_t *text_parent_node = NULL;</code><br>
-
-
-<code> axiom_node_t *text_node = NULL;</code><br>
-
-
-<code> axiom_node_t *ret_node = NULL;</code><br>
-
-
-<br>
-
-
-<code> AXIS2_ENV_CHECK(env, NULL);</code><br>
-
-
-<code> </code><br>
-
-
-<code> </code><i><code>/* Expected request format is :-</code><br>
-
-
-<code> * <ns1:echoString xmlns:ns1="http://localhost:9090/axis2/services/echo"></code><br>
-
-
-<code> * <text>echo5</text></code><br>
-
-
-<code> * </ns1:echoString></code><br>
-
-
-<code> */</code></i><br>
-
-
-<code> </code><b><code>if</code></b><code> (!node) </code><i><code>/* 'echoString' node */</code></i><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INPUT_OM_NODE_NULL, AXIS2_FAILURE);</code><br>
-
-
-<code> printf("Echo client ERROR: input parameter NULL\n");</code><br>
-
-
-<code> </code><b><code>return</code></b><code> NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<br>
-
-
-<code> text_parent_node = AXIOM_NODE_GET_FIRST_CHILD(node, env);</code><br>
-
-
-<code> </code><b><code>if</code></b><code> (!text_parent_node) </code><i><code>/* 'text' node */</code></i><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);</code><br>
-
-
-<code> printf("Echo client ERROR: invalid XML in request\n");</code><br>
-
-
-<code> </code><b><code>return</code></b><code> NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><br>
-
-
-<code> text_node = AXIOM_NODE_GET_FIRST_CHILD(text_parent_node, env);</code><br>
-
-
-<code> </code><b><code>if</code></b><code> (!text_node) </code><i><code>/* actual text to echo */</code></i><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);</code><br>
-
-
-<code> printf("Echo client ERROR: invalid XML in request\n");</code><br>
-
-
-<code> </code><b><code>return</code></b><code> NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><br>
-
-
-<code> </code><b><code>if</code></b><code> (AXIOM_NODE_GET_NODE_TYPE(text_node, env) == AXIOM_TEXT)</code><br>
-
-
-<code> {</code><br>
-
-
-<code> axiom_text_t *text = (axiom_text_t *)AXIOM_NODE_GET_DATA_ELEMENT(text_node, env);</code><br>
-
-
-<code> </code><b><code>if</code></b><code>( text && AXIOM_TEXT_GET_VALUE(text , env))</code><br>
-
-
-<code> {</code><br>
-
-
-<code> axis2_char_t *text_str = AXIOM_TEXT_GET_VALUE(text, env);</code><br>
-
-
-<code> printf("Echoing text value %s \n", text_str);</code><br>
-
-
-<code> ret_node = build_om_programatically(env, text_str);</code><br>
-
-
-<code> }</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><b><code>else</code></b><br>
-
-
-<code> {</code><br>
-
-
-<code> AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);</code><br>
-
-
-<code> printf("Echo client ERROR: invalid XML in request\n");</code><br>
-
-
-<code> </code><b><code>return</code></b><code> NULL;</code><br>
-
-
-<code> }</code><br>
-
-
-<code> </code><br>
-
-
-<code> </code><b><code>return</code></b><code> ret_node;</code><br>
-
-
-<code>}</code><br>
-
-
-<br>
-
-
-<i><code>/* Builds the response content */</code></i><br>
-
-
-<code>axiom_node_t *</code><br>
-
-
-<code>build_om_programatically(const
-axis2_env_t *env, axis2_char_t *text)</code><br>
-
-
-<code>{</code><br>
-
-
-<code> axiom_node_t *echo_om_node = NULL;</code><br>
-
-
-<code> axiom_element_t* echo_om_ele = NULL;</code><br>
-
-
-<code> axiom_node_t* text_om_node = NULL;</code><br>
-
-
-<code> axiom_element_t * text_om_ele = NULL;</code><br>
-
-
-<code> axiom_namespace_t *ns1 = NULL;</code><br>
-
-
-<code> </code><br>
-
-
-<code> ns1 = axiom_namespace_create (env, "http://localhost:9090/axis2/services/echo", "ns1");</code><br>
-
-
-<br>
-
-
-<code> echo_om_ele = axiom_element_create(env, NULL, "echoString", ns1, &echo_om_node);</code><br>
-
-
-<code> </code><br>
-
-
-<code> text_om_ele = axiom_element_create(env, echo_om_node, "text", NULL, &text_om_node);</code><br>
-
-
-<br>
-
-
-<code> AXIOM_ELEMENT_SET_TEXT(text_om_ele, env, text, text_om_node);</code><br>
-
-
-<code> </code><br>
-
-
-<code> </code><b><code>return</code></b><code> echo_om_node;</code><br>
-
-
-<code>}</code><br>
-
-
-</p>
-
-
-
-<h4>Step3 :Write the services.xml file</h4>
-
-
-<p>Axis2/C uses "services.xml" file to keep configurations for a
-Web Service.
-Each Web Service deployed in Axis2/C needs a "services.xml" file
-containing
-the configurations. Note that services.xml has the same semantics as
-Axis2
-Java's services.xml file. Only difference is that for class attributes,
-instead of giving package qualified class name, we use the dll name.
-"services.xml" for echo will be as follows.</p>
-
-
-<pre class="code"><service name="echo"><br> <parameter name="ServiceClass" locked="xsd:false">echo</parameter><br> <description><br> This is a echo service<br> </description><br><br> <operation name="echoString"><br> <parameter name="wsamapping"><br> http://localhost:9090/axis2/services/echo/echoString<br> </parameter><br> </operation><br></service></pre>
-
-
-<p><em></em></p>
-
-
-<p>Name of the service will be the name of the folder with the
-shared library
-and the services.xml, In this example case we will have a folder named
-"echo"
-in which we have the echo.dll (or libecho.so on Linux platform) and
-services.xml file.</p>
-
-
-<p></p>
-
-
-<p>You can write a services.xml file to include a group of
-services instead
-of a single service. This makes management and deployment of a set of
-related
-services very easy. At runtime you can share information between these
-services within a single interaction using the <code>axis2_svc_grp_ctx</code>
-(Service Group Context ). If you hope to use this functionality, the
-services.xml file should have following format.<br>
-
-
-</p>
-
-
-<pre class="code"><serviceGroup><br> <service name="Service1"><br> <!-- details for Service1 --><br> </service><br> <service name="Service2"><br> <!-- details for Service2 --><br> </service><br> <module ref="ModuleName" /><br> <parameter name="serviceGroupParam1" locked="false">value 1</parameter><br></serviceGroup></pre>
-
-
-<p></p>
-
-
-<p>Note : name of the service is a compulsory attribute</p>
-
-
-<p></p>
-
-
-<h4>Step4 :Create the Web Service folder in services folder of
-the
-repository.</h4>
-
-
-<p>In Axis2/C , it is required to create a folder with the
-corresponding
-service/service group name which will contain the shared library
-(compiled
-service) and the services.xml file which describe the web service. So
-for
-this example, we will have to create a folder named "echo", which
-contain the
-services,xml file and echo dll.</p>
-
-
-<h4>Step5 :Archive Based Deployment Model.</h4>
-
-
-<p>Axis2 uses ".aar" (Axis Archive) file as the deployment
-package for the Web Services. Therefore, for echo service we will use
-"echo.aar". (Name of the service will be the name of the archive file)
-To create "echo.aar" user can create a zip file containing echo.so and
-services.xml and rename the zip extension to aar. Then Axis2
-understands it as a service archive.</p>
-
-
-<br>
-
-
-
-<h3>Writing Web Services Skeleton Using Code Generator</h3>
-
-
-<h4><a id="WSDL2Code_tool">WSDL2Code tool</a></h4>
-
-
-<p>Axis2/Java WSDL2Code tool supports generation of Axis2/C stub
-and
-skeleton. Axis2/Java svn revision 414253 and later versions provides
-this
-facility.. A basic guide for the tool can be found <a href="http://ws.apache.org/axis2/1_0/userguide2.html#Writing_Web_Services_by_Code_Generating_Skeleton">
-here</a></p>
-
-
-<p>We will run the tool with the following parameters and
-generate the
-skeleton and the other required files to support ADB (Axis Data
-Binding). In
-order to run the tool, <span style="font-weight: bold;">set all the .jar library files in the Axis2/Java
-to
-the classpath</span>. To generate code with no data binding support, just
-replace -d
-adb -u with -d none</p>
-
-
-<pre><br>java -Dorg.apache.adb.properties=/org/apache/axis2/schema/c-schema-compile.properties org.apache.axis2.wsdl.WSDL2Code <br> -uri interoptestdoclitparameters.wsdl -ss -sd -d adb -u<br> </pre>
-
-
-<p>If you need an XML in/out programming model, you can just
-ignore the data
-binding support by setting following parameters. Give "<code>-l c</code>" option to enable c language code generation.</p>
-
-
-<pre><br>java org.apache.axis2.wsdl.WSDL2Code -uri interoptestdoclitparameters.wsdl -ss -sd -d none -l c<br> </pre>
-
-
-<p>The WSDL <code>interoptestdoclitparameters.wsdl</code> can be found in
-<axis2_src_dir>/test/resources directory. This is used to
-generate stub
-and skeleton code throughout this user guide.</p>
-
-
-
-
-<h4><a id="Implement_the_Business_Logic">Implement
-the Business Logic</a></h4>
-
-
-Locate the skeleton source file from the generated files:
-"<code>axis2_WSDLInteropTestDocLitService.c</code>". You can go through the rest of
-the
-guide to add the business logic to the following operations in the
-WSDL.
-<ul>
-
-
- <li>echoString - Operation that echoes a String value</li>
-
-
- <li>echoStringArray - Operation that accept string array as the
-input and echoes them back</li>
-
-
- <li>echoStruct - Operation that accept a Struct as the input
-and echoes them back</li>
-
-
-</ul>
-
-
-<p></p>
-
-
-<p>Complete skeleton source file for the above operations can be
-found under
-<axis2_src_dir>/samples/codegen/server/interop_doc2
-directory with the
-name "<code>axis2_WSDLInteropTestDocLitService.c</code>".</p>
-
-
-<h4><a id="echoString">echoString</a></h4>
-
-
-<p>If you generate the code with data binding support, you will
-find the
-following code segment in the "<code>axis2_WSDLInteropTestDocLitService.c</code>"
-Fill the
-business logic inside this function as shown below.</p>
-
-
-<pre>axis2_echoStringResponse_t*<br>axis2_WSDLInteropTestDocLitService_echoString<br> (const axis2_env_t* env ,axis2_echoString_t* param6 )<br>{<br> /* Todo fill this with the necessary business logic */<br>}</pre>
-
-
-<p></p>
-
-
-<p>Once filled with the business logic, it will be as follows.
-The code is
-simple and the inline comments provide some explanation.</p>
-
-
-<pre>axis2_echoStringResponse_t*<br>axis2_WSDLInteropTestDocLitService_echoString<br> (const axis2_env_t* env ,axis2_echoString_t* param6 )<br>{<br> axis2_echoString_t* echo_in = param6;<br> axis2_echoStringResponse_t* echo_out = NULL;<br><br> char* echo_string = NULL;<br> <br> /* retrieve the string input */<br> echo_string = AXIS2_ECHOSTRING_GET_PARAM0 ( echo_in, env );<br><br> /* create the response and set the output string */<br> echo_out = axis2_echoStringResponse_create ( env );<br> AXIS2_ECHOSTRUCTRESPONSE_SET_RETURN ( echo_out, env, echo_string );<br><br> return echo_out;<br>}</pre>
-
-
-<p></p>
-
-
-<h4><a id="echoStringArray">echoStringArray</a></h4>
-
-
-<pre>axis2_echoStringArrayResponse_t*<br>axis2_WSDLInteropTestDocLitService_echoStringArray<br> (const axis2_env_t* env ,axis2_echoStringArray_t* param2 )<br><br>{<br> axis2_echoStringArray_t* echo_in = param2;<br> axis2_echoStringArrayResponse_t* echo_out = NULL;<br> axis2_ArrayOfstring_literal_t* array_in = NULL;<br> axis2_ArrayOfstring_literal_t* array_out = NULL;<br> char ** string_array = NULL;<br> int string_array_length = 0;<br> <br> /* retrieve the array from input*/<br> array_in = AXIS2_ECHOSTRINGARRAY_GET_PARAM0( echo_in, env);<br> /* retrieve the string_array and array length */<br> string_array =<br> AXIS2_ARRAYOFSTRING_LITERAL_GET_STRING <br> (array_in, env,&string_array_length );<br> <br> /* create the output array and set the string array and length */<br> array_out = axis2_ArrayOfstring_literal_create ( env );<br> AXIS2_ARRAYOFSTRING_LITERAL_SET_STRING(<br> array_out, env, string_array, string_array_length );<br> <br> /* create the response and set the ou
tput*/<br> echo_out = axis2_echoStringArrayResponse_create ( env );<br> AXIS2_ECHOSTRINGARRAYRESPONSE_SET_RETURN ( echo_out, env , array_out );<br> <br> return echo_out;<br><br>}</pre>
-
-
-<p></p>
-
-
-<h4><a id="echoStruct">echoStruct</a></h4>
-
-
-<pre>axis2_echoStructResponse_t*<br>axis2_WSDLInteropTestDocLitService_echoStruct<br> (const axis2_env_t* env ,axis2_echoStruct_t* param4 )<br><br>{<br> axis2_echoStruct_t* echo_in = param4;<br> axis2_echoStructResponse_t* echo_out = NULL;<br> axis2_SOAPStruct_t* struct_in = NULL;<br> axis2_SOAPStruct_t* struct_out = NULL;<br> <br> float float_val = 0;<br> int int_val = 0;<br> char* string_val = NULL;<br> <br> /* retrieve the structure from input */<br> struct_in = AXIS2_ECHOSTRUCT_GET_PARAM0( echo_in, env);<br><br> /* retrieve each value from the structure */ <br> float_val = AXIS2_SOAPSTRUCT_GET_VARFLOAT ( struct_in, env);<br> int_val = AXIS2_SOAPSTRUCT_GET_VARINT ( struct_in, env);<br> string_val = AXIS2_SOAPSTRUCT_GET_VARSTRING ( struct_in, env);<br> <br> /* create the output structure and set values */<br> struct_out = axis2_SOAPStruct_create( env );<br> AXIS2_SOAPSTRUCT_SET_VARFLOAT ( struct_out, env, float_val );<br> AXIS2_SOAPSTRUCT_SET_VARINT ( struct_out, env, int_
val );<br> AXIS2_SOAPSTRUCT_SET_VARSTRING ( struct_out, env, string_val );<br> <br> /* create the response and set the output structure*/<br> echo_out = axis2_echoStructResponse_create ( env );<br> AXIS2_ECHOSTRUCTRESPONSE_SET_RETURN ( echo_out, env, struct_out );<br> <br> return echo_out;<br>}<br></pre>
-
-
-<h4><a id="services_xml">services.xml</a></h4>
-
-
-Axis2 uses "services.xml" to hold the configurations for a particular
-Web
-service deployed in the Axis2 engine. When we generate the skeleton
-using the
-WSDL2Java tool, it will also generate the required services.xml for
-this Web
-service as well. This is essential to <a href="#deploy">deploy
-the
-service</a>. Please refer to the <a href="#step3">Write
-the services.xml</a>
-section of this guide to learn more about services.xml
-<p></p>
-
-
-<h3>Deploy the Web Service</h3>
-
-
-<p>We simply put our service folder or the ".aar" file to the
-services
-directory. You need restart the server for the engine to pick this
-service.
-</p>
-
-
-<h2>Web Service Clients UsingAxis2/C</h2>
-
-
-<p>Now let's see how we can write a Web Service Client to consume
-a Web
-Service.</p>
-
-
-<p>Web Services can be used to provide wide range of
-functionality to the
-users ranging from simple, less time consuming operations
-such as
-"getStockQuote" to time consuming business services. When we
-utilize
-(invoke using client applications) these Web Services, we cannot use
-some
-simple generic invocation paradigm that suites all the timing
-complexities
-involved in the service operations. For example, if we use a single
-transport
-channel (such as HTTP) to invoke a Web Service with an IN-OUT operation
-that
-take long time to complete, then most of the time we may end up with
-"connection time outs". On the other hand, if there are simultaneous
-service
-invocations that we need to perform from a single client
-application,
-then the use of a "blocking" client API will degrade the performance of
-the
-client application. Similarly there are various other consequences such
-as
-One-Way transports that come in to play when we need them. Let's try to
-analyze some common service invocation paradigms.</p>
-
-
-<p>Many Web service engines provide the users with a Blocking and
-Non-Blocking client APIs.</p>
-
-
-<ul>
-
-
- <li>
-
- <p style="margin-bottom: 0in;"><b>Blocking API</b>
--Once the service invocation is called, the client application hangs
-and only gets control back when the operation completes, after which
-client receives a response or a fault. This is the simplest way of
-invoking Web Services and it also suites many business situations.</p>
-
-
- </li>
-
-
- <li><b>Non-Blocking API</b>- This is a callback or
-polling based API, hence once a service invocation is called, the
-client application immediately gets the control back and the response
-is retrieved using the callback object provided. This approach provides
-the flexibility to the client application to invoke several Web
-Services simultaneously without blocking the operation already invoked.</li>
-
-
-</ul>
-
-
-<p>Both these mechanisms work in the API level. Let's name
-the
-asynchronous behavior that we can get using the <strong>Non-Blocking
-API</strong> as <b>API Level Asynchrony.</b></p>
-
-
-<p>Both these mechanisms use single transport connection to send
-the request
-and to receive the response. They severely lags the capability of using
-two
-transport connections for the request and the response (either One-Way
-of
+<p>Both these mechanisms work in the API level. Let's name the asynchronous
+behavior that we can get using the <strong>Non-Blocking API</strong> as
+<b>API Level Asynchrony.</b></p>
+
+<p>Both these mechanisms use single transport connection to send the request
+and to receive the response. They severely lag the capability of using two
+transport connections for the request and the response (either One-Way of
Two-Way). So both these mechanisms fail to address the problem of long
running transactions (the transport connection may time-out before the
operation completes). A possible solution would be to use <strong>two
-separate transport connections for request and response</strong>.
-The
+separate transport connections for request and response</strong>. The
asynchronous behavior that we gain using this solution can be called
-<b>Transport Level Asynchrony</b>.</p>
-
-
-<p>By combining API Level Asynchrony & Transport Level
-Asynchrony we can
-obtain four different invocation patterns for Web services as shown in
-the
-following table.</p>
-
-
-<p></p>
-
-
-<table border="1" cellpadding="0" cellspacing="0" width="100%">
-
-
- <tbody>
-
-
- <tr>
-
-
- <td><strong>API (Blocking/Non-Blocking)</strong></td>
-
+<b>Transport Level Asynchrony</b>.</p>
- <td><strong> Dual Transports (Yes/No)</strong></td>
+<p>By combining API Level Asynchrony & Transport Level Asynchrony we can
+obtain four different invocation patterns for Web services as shown in the
+following table.</p>
+<p></p>
+<table border="1" cellpadding="0" cellspacing="0" width="100%">
+ <tbody>
+ <tr>
+ <td><strong>API (Blocking/Non-Blocking)</strong></td>
+ <td><strong> Dual Transports (Yes/No)</strong></td>
<td><strong>Description</strong></td>
-
-
</tr>
-
-
<tr>
-
-
<td>Blocking</td>
-
-
<td>No</td>
-
-
<td>Simplest and the familiar invocation pattern</td>
-
-
</tr>
-
-
<tr>
-
-
<td>Non-Blocking</td>
-
-
<td>No</td>
-
-
<td>Using callbacks or polling</td>
-
-
</tr>
-
-
<tr>
-
-
<td>Blocking</td>
-
-
<td>Yes</td>
-
-
- <td>This is useful when the service operation is IN-OUT in
-nature but the transport used is One-Way (e.g. SMTP)</td>
-
-
+ <td>This is useful when the service operation is IN-OUT in nature but
+ the transport used is One-Way (e.g. SMTP)</td>
</tr>
-
-
<tr>
-
-
<td>Non-Blocking</td>
-
-
<td>Yes</td>
-
-
- <td>This is can be used to gain the maximum asynchronous
-behavior. No blocking in the API level and also in the transport level</td>
-
-
+ <td>This is can be used to gain the maximum asynchronous behavior. No
+ blocking in the API level and also in the transport level</td>
</tr>
-
-
-
</tbody>
</table>
+<p>Axis2/C provides the user with all these possibilities to invoke Web
+services.</p>
-<p>Axis2/C provides the user with all these possibilities to
-invoke Web
-Services.</p>
-
-
-<p>Below we describe how to write Web Services Clients using
-Axis2/C.</p>
-
-
-
-<h3>Writing Web Service Clients Using Axis2's Primary APIs</h3>
-
-
+<p>Below we describe how to write Web Services Clients using Axis2/C.</p>
+<h3><a name="Writing_Web_Service_Clients_using_Axis2%27s_Primary_APIs">Writing Web Service Clients Using Axis2's Primary APIs</a></h3>
+<a id="EchoBlockingClient"></a>
<h4>echo_blocking Client</h4>
-
-<p>Axis2/C provides the user with several invocation patterns for
-Web
+<p>Axis2/C provides the user with several invocation patterns for Web
Services, ranging from pure blocking single channel invocations to a
-non-blocking dual channel invocations. Let's first see how we can write
-a
+non-blocking dual channel invocations. Let's first see how we can write a
client to invoke "echo" operation of "echo" service using the simplest
blocking invocation. The client code you need to write is as follows.</p>
+<pre> <br /> <span style="color: rgb(36, 193, 19);">/* Create EPR with given address */</span><br />endpoint_ref = axis2_endpoint_ref_create(env, address);<br /><span style="color: rgb(36, 193, 19);">/* Setup options */</span><br />options = axis2_options_create(env);<br />AXIS2_OPTIONS_SET_TO(options, env, endpoint_ref);<br /><span style="color: rgb(36, 193, 19);">/* Set the deploy folder */</span><br />client_home = AXIS2_GETENV("AXIS2C_HOME");<br />if (!client_home)<br />client_home = "../../deploy";<br /><span style="color: rgb(36, 193, 19);">/* Create service client */</span><br />svc_client = axis2_svc_client_create(env, client_home);<br />if (!svc_client)<br />{<br />printf("Error creating service client\n");<br />AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"<br />" %d :: %s", env->error->error_number,<br />AXIS2_ERROR_GET_MESSAGE(env->error));<br />}<br /><span style="color: rgb(36, 193, 19);">/* Set service client options */</
span><br />AXIS2_SVC_CLIENT_SET_OPTIONS(svc_client, env, options); <span style="color: rgb(36, 193, 19);">/* Build the SOAP request message payload using OM API.*/</span><br />payload = build_om_payload_for_echo_svc(env);<br /><span style="color: rgb(36, 193, 19);">/* Send request */</span><br />ret_node = AXIS2_SVC_CLIENT_SEND_RECEIVE(svc_client, env, payload);<br /><span style="color: rgb(36, 193, 19);">/* Print result */</span><br />if(ret_node)<br />{<br />axis2_char_t *om_str = NULL;<br />om_str = AXIOM_NODE_TO_STRING(ret_node, env);<br />if (om_str)<br />printf("\nReceived OM : %s\n", om_str);<br />printf("\necho client invoke SUCCESSFUL!\n");<br />}<br />else<br />{<br />AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"<br />" %d :: %s", env->error->error_number,<br />AXIS2_ERROR_GET_MESSAGE(env->error));<br />printf("echo client invoke FAILED!\n");<br />}</pre>
-
-<pre> <br> <span style="color: rgb(36, 193, 19);">/* Create EPR with given address */</span><br>endpoint_ref = axis2_endpoint_ref_create(env, address);<br><span style="color: rgb(36, 193, 19);">/* Setup options */</span><br>options = axis2_options_create(env);<br>AXIS2_OPTIONS_SET_TO(options, env, endpoint_ref);<br><span style="color: rgb(36, 193, 19);">/* Set the deploy folder */</span><br>client_home = AXIS2_GETENV("AXIS2C_HOME");<br>if (!client_home)<br>client_home = "../../deploy";<br><span style="color: rgb(36, 193, 19);">/* Create service client */</span><br>svc_client = axis2_svc_client_create(env, client_home);<br>if (!svc_client)<br>{<br>printf("Error creating service client\n");<br>AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"<br>" %d :: %s", env->error->error_number,<br>AXIS2_ERROR_GET_MESSAGE(env->error));<br>}<br><span style="color: rgb(36, 193, 19);">/* Set service client options */</span><br>AXIS2_SVC_CLIENT_SET_OPTIONS(
svc_client, env, options); <span style="color: rgb(36, 193, 19);">/* Build the SOAP request message payload using OM API.*/</span><br>payload = build_om_payload_for_echo_svc(env);<br><span style="color: rgb(36, 193, 19);">/* Send request */</span><br>ret_node = AXIS2_SVC_CLIENT_SEND_RECEIVE(svc_client, env, payload);<br><span style="color: rgb(36, 193, 19);">/* Print result */</span><br>if(ret_node)<br>{<br>axis2_char_t *om_str = NULL;<br>om_str = AXIOM_NODE_TO_STRING(ret_node, env);<br>if (om_str)<br>printf("\nReceived OM : %s\n", om_str);<br>printf("\necho client invoke SUCCESSFUL!\n");<br>}<br>else<br>{<br>AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"<br>" %d :: %s", env->error->error_number,<br>AXIS2_ERROR_GET_MESSAGE(env->error));<br>printf("echo client invoke FAILED!\n");<br>}</pre>
-
-
-<p>The comments in the above code explains the code. In simple
-terms, these
+<p>The comments in the above code explains the code. In simple terms, these
are the steps:</p>
-
-
<ol>
-
-
<li>Set up the options to be used in the invocation.</li>
-
-
<li>Create the service client.</li>
-
-
<li>Set the options to service client.</li>
-
-
<li>Build the XML payload to be sent out using AXIOM.</li>
-
-
<li>Send payload and receive result XML as OM.</li>
-
-
<li>Consume result.</li>
-
-
</ol>
-
-<p>Options can be used to define the invocation parameters such
-as target
-endpoint, soap version, addressing parameters, etc.. When creating
-service
-client, the deployment folder has to be passed as a parameter. It is
-from the
-deploy folder, the configuration is picked up, using the axis2.xml
-file. The
-send_receive function of the service client sends the XML given as
-payload to
-the server side and returns the result received, basically this is the
-XML
-in/out model. Once the result is received, the user can consume the
-result in
-whichever the way (s)he wishes.</p>
-
-
-
+<p>Options can be used to define the invocation parameters such as target
+endpoint, soap version, addressing parameters, etc. When creating service
+client, the deployment folder has to be passed as a parameter. It is from the
+deploy folder, the configuration is picked up, using the axis2.xml file. The
+send_receive function of the service client sends the XML given as a payload
+to the server side and returns the result received. Basically this is the XML
+in/out model. Once the result is received, the user can consume the result in
+whichever the way(s) he wishes.</p>
+<a id="EchoNonBlockingClient"></a>
<h4>echo_non_blocking Client</h4>
-
-<p>In the echo_blocking client once the "send_receive" function
-is called,
-the client is blocked till the operation is completed. This behavior is
-not
-desirable when there are many Web Service invocations to be done in a
-single
-client application or within a GUI. A solution would be to use a
-non-blocking
-API to invoke Web Services. Axis2/C provides a callback based
-non-blocking
+<p>In the echo_blocking client once the "send_receive" function is called,
+the client is blocked till the operation is completed. This behavior is not
+desirable when there are many Web service invocations to be done in a single
+client application or within a GUI. A solution would be to use a non-blocking
+API to invoke Web services. Axis2/C provides a callback based non-blocking
API for users.</p>
-
<p>A sample client for this can be found under
"<axis2c_home>/samples/user_guide/clients" with the name
-echo_non_blocking.c.
-The changes that user may have to do with respect to the
-"echo_blocking"
-client to make it non-blocking would be as follows:</p>
-
-
+echo_non_blocking.c. The changes that user may have to do with respect to the
+"echo_blocking" client in order to make it non-blocking, would be as
+follows:</p>
<pre style="margin-bottom: 0.2in;">AXIS2_SVC_CLIENT_SEND_RECEIVE_NON_BLOCKING(svc_client, env, payload, callback);</pre>
-
-<p>Unlike "send_receive", "send_receive_non_blocking" accepts a
-callback
-struct in addition to payload. Axis2/C client API provides a callback
-struct
+<p>Unlike "send_receive", "send_receive_non_blocking" accepts a callback
+struct in addition to payload. Axis2/C client API provides a callback struct
with the following associated functions:</p>
+<pre>axis2_status_t (AXIS2_CALL *<br />on_complete)(<br /> struct axis2_callback *callback,<br /> const axis2_env_t *env);<br /><br />axis2_status_t (AXIS2_CALL *<br />on_error)(<br /> struct axis2_callback *callback,<br /> const axis2_env_t *env,<br /> int exception);<br /><br />axis2_bool_t (AXIS2_CALL *<br />get_complete)(<br /> struct axis2_callback *callback,<br /> const axis2_env_t *env);</pre>
-
-<pre>axis2_status_t (AXIS2_CALL *<br>on_complete)(<br> struct axis2_callback *callback,<br> const axis2_env_t *env);<br><br>axis2_status_t (AXIS2_CALL *<br>on_error)(<br> struct axis2_callback *callback,<br> const axis2_env_t *env,<br> int exception);<br><br>axis2_bool_t (AXIS2_CALL *<br>get_complete)(<br> struct axis2_callback *callback,<br> const axis2_env_t *env);</pre>
-
-
-<p>The user is expected to implement the "on_complete " and
-"on_error "
+<p>The user is expected to implement the "on_complete " and "on_error "
functions and set them on the callback using the "set_on_complete" and
-"set_on_error" API calls. In the sample, on complete is implemented by
-"<code>echo_callback_on_complete</code>" function and is
-set on the callback struct
+"set_on_error" API calls. In the sample, ''on complete'' is implemented by
+"echo_callback_on_complete" function and is set on the callback struct
created as shown below:</p>
-
-
<pre style="margin-bottom: 0.2in;">AXIS2_CALLBACK_SET_ON_COMPLETE(callback, echo_callback_on_complete);</pre>
-
-<p>Axis2/C engine calls the on_complete method once the Web
-Service response
-is received by the Axis2/C client API (that is service_client). This
-will
-eliminate the blocking nature of the Web Service invocations and
-provides the
-user with the flexibility to use non-blocking API for Web Service
-clients.</p>
-
-
-<p>Please have a look at the echo_non_blocking.c for more details.</p>
-
-
-
+<p>Axis2/C engine calls the "on_complete" method once the Web service
+response is received by the Axis2/C client API (that is service_client). This
+will eliminate the blocking nature of the Web service invocations and
+provides the user with the flexibility to use non-blocking API for Web
+service clients.</p>
+
+<p>Please have a look at the echo_non_blocking.c file located at
+"<axis2c_home>/samples/user_guide/client" for more details.</p>
+<a id="EchoNonBlockingDualClient"></a>
<h4>echo_non_blocking_dual Client</h4>
-
-<p>The solution provided by the non-blocking API has one
-limitation when it
-comes to Web Service invocations which takes a long time to
-complete. The
-limitation is due to the use of a single transport connection to invoke
-the Web
-Service and to retrieve the response. In other words, client API
-provides a
-non blocking invocation mechanism for the users, but the request and
-the
-response comes in a single transport (Two-Way transport) connection
-(like
-HTTP). Long running Web Service invocations or Web Service invocations
-using
+<p>The solution provided by the non-blocking API has one limitation when it
+comes to Web service invocations which takes a long time to complete. The
+limitation is due to the use of a single transport connection to invoke the
+Web service and to retrieve the response. In other words, client API provides
+a non blocking invocation mechanism for the users, but the request and the
[... 525 lines stripped ...]
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org