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/18 13:17:20 UTC

svn commit: r465210 [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=465210&r1=465209&r2=465210
==============================================================================
--- webservices/axis2/trunk/c/xdocs/docs/userguide.html (original)
+++ webservices/axis2/trunk/c/xdocs/docs/userguide.html Wed Oct 18 04:17:19 2006
@@ -1,993 +1,1002 @@
-<?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" />
-  <title>Axis2/C User's Guide</title>
-  <meta name="generator" content="amaya 9.2.1, see http://www.w3.org/Amaya/"
-  />
-</head>
-
-<body xml:lang="en">
-<h1>Apache Axis2/C User's Guide</h1>
-
-<h2>Content</h2>
-<ul>
-  <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>
-    <ul>
-      <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>
-            <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 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>
-        <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="#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>
-    <ul>
-      <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="#EchoNonBlockingClient">echo_non_blocking
-          Client</a></li>
-          <li><a href="#EchoNonBlockingDualClient">echo_non_blocking_dual
-            Client</a></li>
-          <li><a href="#EchoBlockingDualClient">echo_blocking_dual
-          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>
-        <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>
-        </ul>
-      </li>
-    </ul>
-  </li>
-  <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="#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>
-    </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
-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>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 (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>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
-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>
-
-<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>
-
-<h3><a name="Writing_Web_Services_Using_Axis2_C">Writing Web Services Using Axis2/C</a></h3>
-
-<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>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
-Service?</a></h4>
-
-<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>
-  <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>
-<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
-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>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-&gt;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-&gt;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>        &amp;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-&gt;func_array)</code><br
-/>
-<code>    {</code><br />
-<code>        AXIS2_ARRAY_LIST_FREE(svc_skeleton-&gt;func_array, env);</code><br
-/>
-<code>        svc_skeleton-&gt;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-&gt;ops)</code><br
-/>
-<code>    {</code><br />
-<code>        AXIS2_FREE(env-&gt;allocator, svc_skeleton-&gt;ops);</code><br
-/>
-<code>        svc_skeleton-&gt;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-&gt;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>/*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-&gt;allocator, </code><br />
-<code>        </code><b><code>sizeof</code></b><code>(axis2_svc_skeleton_t));</code><br
-/>
-<br />
-<code>    svc_skeleton-&gt;ops = AXIS2_MALLOC(</code><br />
-<code>        env-&gt;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-&gt;ops-&gt;free = echo_free;</code><br />
-<code>    svc_skeleton-&gt;ops-&gt;init = echo_init;</code><br />
-<code>    svc_skeleton-&gt;ops-&gt;invoke = echo_invoke;</code><br />
-<code>    svc_skeleton-&gt;ops-&gt;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>
-
-<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>
-<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>     * &lt;ns1:echoString xmlns:ns1="http://localhost:9090/axis2/services/echo"&gt;</code><br
-/>
-<code>     *      &lt;text&gt;echo5&lt;/text&gt;</code><br />
-<code>     * &lt;/ns1:echoString&gt;</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-&gt;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-&gt;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-&gt;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 &amp;&amp; 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-&gt;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, &amp;echo_om_node);</code><br
-/>
-<code>    </code><br />
-<code>    text_om_ele = axiom_element_create(env, echo_om_node, "text", NULL, &amp;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>
-
-<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">&lt;service name="echo"&gt;<br /> &lt;parameter name="ServiceClass" locked="xsd:false"&gt;echo&lt;/parameter&gt;<br /> &lt;description&gt;<br /> This is a echo service<br /> &lt;/description&gt;<br /><br /> &lt;operation name="echoString"&gt;<br /> &lt;parameter name="wsamapping"&gt;<br /> http://localhost:9090/axis2/services/echo/echoString<br /> &lt;/parameter&gt;<br /> &lt;/operation&gt;<br />&lt;/service&gt;</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">&lt;serviceGroup&gt;<br /> &lt;service name="Service1"&gt;<br /> &lt;!-- details for Service1 --&gt;<br /> &lt;/service&gt;<br /> &lt;service name="Service2"&gt;<br /> &lt;!-- details for Service2 --&gt;<br /> &lt;/service&gt;<br /> &lt;module ref="ModuleName" /&gt;<br /> &lt;parameter name="serviceGroupParam1" locked="false"&gt;value 1&lt;/parameter&gt;<br />&lt;/serviceGroup&gt;</pre>
-
-<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>
-
-<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>
-
-<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
-&lt;axis2_src_dir&gt;/test/resources directory. This is used to generate stub
-and skeleton code throughout this User's 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>Complete skeleton source file for the above operations can be found under
-&lt;axis2_src_dir&gt;/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>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>
-
-<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,&amp;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>
-
-<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>
-
-<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>
-
-<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>
-
-<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
-asynchronous behavior that we gain using this solution can be called
-<b>Transport Level Asynchrony</b>.</p>
-
-<p>By combining API Level Asynchrony &amp; 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>
-    </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>
-    </tr>
-  </tbody>
-</table>
-
-<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><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
-Services, ranging from pure blocking single channel invocations to 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-&gt;log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"<br />" %d :: %s", env-&gt;error-&gt;error_number,<br />AXIS2_ERROR_GET_MESSAGE(env-&gt;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-&gt;log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"<br />" %d :: %s", env-&gt;error-&gt;error_number,<br />AXIS2_ERROR_GET_MESSAGE(env-&gt;error));<br />printf("echo client invoke FAILED!\n");<br />}</pre>
-
-<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 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
-API for users.</p>
-
-<p>A sample client for this can be found under
-"&lt;axis2c_home&gt;/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 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
-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>
-
-<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
-"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 file located at
-"&lt;axis2c_home&gt;/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
-One-Way transports (like SMTP) cannot be utilized by simply using a non
-blocking invocation.</p>
-
-<p>The trivial solution is to use separate transport connections (either
-One-Way or Two-Way) for the request and response. The next problem that needs
-to be solved is the correlation (correlating the request and the response).
-<a href="http://www.w3.org/2002/ws/addr/">WS-Addressing</a> provides a neat
-solution to this using &lt;wsa:MessageID&gt; and &lt;wsa:RelatesTo&gt;
-headers. Axis2/C provides support for addressing  based correlation mechanism
-and a compliant client API to invoke Web services with two transport
-connections.</p>
-
-<p>Users can select between blocking or non-blocking APIs for the Web service
-clients with two transport connections. By simply using a boolean flag, the
-same API can be used to invoke Web services (IN-OUT operations) using two
-separate transport connections. All that you have to do is to set
-"use_separate_listener" to true in options:</p>
-<pre>AXIS2_OPTIONS_SET_USE_SEPERATE_LISTENER(options, env, AXIS2_TRUE);</pre>
-
-<p>In addition to setting the use_separate_listener to true, to use dual
-transports one has to"engage" the addressing module.</p>
-
-<h5>Engaging Addressing on Server Side</h5>
-
-<p>To engage the addressing module simply add a module reference for
-addressing in the "axis2.xml" configuration file. This can be done by adding
-the following line to "axis2.xml" file in the deployment folder.</p>
-<pre style="margin-bottom: 0.2in;"> &lt;module ref="addressing"/&gt;</pre>
-
-<p>Note: Once you modify the "axis2.xml" file you have to restart the server.
-You also have to have the addressing module installed in the modules folder
-of the deployment folder. This is done by default when you make the
-installation.</p>
-
-<h5>Engaging Addressing on Client Side</h5>
-
-<p>There are two ways of doing this:</p>
-<ol>
-  <li>Engage addressing globally. This can be done by following the same
-    steps as done in the case of the server side; add module reference to
-    axis2.xml and have the module installed in the modules folder of the
-    deploy folder.</li>
-  <li>Engage the module on service client using the service_client API.
-    <pre>AXIS2_SVC_CLIENT_ENGAGE_MODULE(svc_client, env, AXIS2_MODULE_ADDRESSING);</pre>
-  </li>
-</ol>
-
-<p>Once addressing is engaged, echo_non_blocking_dual client would work
-perfectly. Note that by default, Axis2/C comes with addressing enabled
-globally.</p>
-<a id="EchoBlockingDualClient"></a>
-<h4>echo_blocking_dual Client</h4>
-
-<p>This is again a Two-Way transport request/response client, but this time,
-we use a Blocking API in the client code. Sample code for this can be found
-in the "&lt;axis2c_home&gt;/samples/user_guide/clients/" directory and the
-explanation is similar to the <a
-href="#EchoNonBlockingDualClient">echo_non_blocking_dual client</a>, except
-that here we do not use a callback object to handle response. This is a very
-useful mechanism when the service invocation is IN-OUT in nature and the
-transports are One-Way (e.g. SMTP). For the sample client we use two HTTP
-connections for request and response.</p>
-<a id="Writing_Web_Clients_Using_Code_Generator"></a>
-<h3>Writing Web Service Clients using Code Generation with Data Binding
-Support</h3>
-
-<p>Axis2 code generator provides the data binding support for Web service
-client generation as well. You can generate the required stubs from a given
-WSDL with the other supporting files. Use the following parameters to
-generate the Axis2/C stub code with the data binding support. You should have
-<a
-href="http://svn.apache.org/viewvc/webservices/axis2/trunk/java">Axis2/Java
-source SVN</a> revision 414253 or later to generate Axis2/C code</p>
-<pre><br />java WSDL2Code -Dorg.apache.adb.properties=/org/apache/axis2/schema/c-schema-compile.properties<br /> -uri interoptestdoclitparameters.wsdl -d adb -u<br /> </pre>
-
-<p>In order to ignore the data binding support (to use XML in/out model),
-just use following parameters.</p>
-<pre><br />java WSDL2Code -uri interoptestdoclitparameters.wsdl -d none<br /> </pre>
-
-<p>The following section demonstrates how to use the generated code using the
-wsdl file "interoptestdoclitparameters.wsdl" to implement the client business
-logic.</p>
-<a id="Codegenerator_Client_echoString"></a>
-<h4>Client for echoString operation</h4>
-<pre>#include "axis2_WSDLInteropTestDocLitService_stub.h"<br /><br />/*<br /> * demonstrates how to execute the service using databinding<br /> */<br />void invoke_service_using_databinding ( axis2_stub_t* stub,<br /> const axis2_env_t* env );<br />int main(int argc, char** argv)<br />{<br /> /* variables to keep the environment */<br /> axis2_env_t* env = NULL;<br /> axis2_char_t* client_home = NULL;<br /> axis2_char_t* endpoint_uri =NULL;<br /> axis2_stub_t* stub= NULL;<br /> <br /> /* endpoint uri: if it is NULL endpoint will be picked from the WSDL */ <br /> endpoint_uri = "http://localhost:9090/axis2/services/WSDLInteropTestDocLitService";<br /><br /> env = axis2_env_create_all( "codegen_utest_blocking.log", <br /> AXIS2_LOG_LEVEL_TRACE);<br /><br /> /* Set up deploy folder.*/<br /> client_home = AXIS2_GETENV("AXIS2C_HOME");<br /> if (!client_home)<br /> client_home = "../../../deploy";<br /> <br /> /* create the stub using generated code */<br /> stub = axis2_WSDLInter
 opTestDocLitService_stub_create( env, client_home , endpoint_uri); <br /> <br /> /* calls the service*/<br /> invoke_service_using_databinding ( stub, env );<br /><br /> return 0;<br />}<br /><br />void invoke_service_using_databinding ( axis2_stub_t* stub,<br /> const axis2_env_t* env )<br />{<br /> /* variables used by databinding */<br /> axis2_echoString_t* echo_in = NULL;<br /> axis2_echoStringResponse_t* echo_out = NULL;<br /> <br /> /* variables to store data */<br /> char* echo_str = "hello";<br /> char* return_echo_str = NULL;<br /><br /> /* create the input params using databinding */<br /> echo_in = axis2_echoString_create( env );<br /> AXIS2_ECHOSTRING_SET_PARAM0( echo_in, env, echo_str );<br /><br /> /* invoke the web service method*/<br /> echo_out = axis2_echoString( stub, env, echo_in );<br /> <br /> /* return the output params using databinding */<br /> return_echo_str = AXIS2_ECHOSTRUCTRESPONSE_GET_RETURN( echo_out, env );<br /> <br /> /* print the result *
 /<br /> printf ( "returned string %s\n", return_echo_str );<br /><br />} </pre>
-<a id="Codegenerator_Client_echoStringArray"></a>
-<h4>Client for echoStringArray operation</h4>
-You can change the <code>invoke_service_using_databinding</code> function to
-invoke the echoStringArray operation as follows.
-<pre>void invoke_service_using_databinding ( axis2_stub_t* stub,<br /> const axis2_env_t* env )<br />{<br /> /* variables used by databinding */<br /> axis2_echoStringArray_t* echo_in = NULL;<br /> axis2_echoStringArrayResponse_t* echo_out = NULL;<br /> axis2_ArrayOfstring_literal_t* array_in = NULL;<br /> axis2_ArrayOfstring_literal_t* array_out = NULL;<br /><br /> /* variables to store data */<br /> char *string_array[]= { "test","this","array" };<br /> int array_length = 3;<br /><br /> char **string_return_string_array = NULL;<br /> int return_array_length = 0;<br /> int i = 0; <br /> <br /> /*create the input array and set the string array and length*/<br /> array_in = axis2_ArrayOfstring_literal_create (env );<br /> AXIS2_ARRAYOFSTRING_LITERAL_SET_STRING( array_in, env,<br /> string_array, array_length );<br /><br /> /* create the request and set the inputs */<br /> echo_in = axis2_echoStringArray_create ( env );<br /> AXIS2_ECHOSTRINGARRAY_SET_PARAM0( echo_in, env, arr
 ay_in );<br /><br /> /* invoke the web service method*/<br /> echo_out = axis2_echoStringArray( stub, env, echo_in );<br /><br /> /* return the output params using databinding */<br /> array_out = AXIS2_ECHOSTRINGARRAYRESPONSE_GET_RETURN( echo_out, env ); <br /> <br /> /* retrieve the string array values and length */<br /> string_return_string_array = AXIS2_ARRAYOFSTRING_LITERAL_GET_STRING<br /> ( array_out, env, &amp;return_array_length );<br /><br /> /* print the output */<br /> for ( i = 0; i &lt; return_array_length ; i ++ )<br /> {<br /> printf("value%d: %s \n", i, string_return_string_array[i] );<br /> }<br />}</pre>
-<a id="Codegenerator_Client_echoStruct"></a>
-<h4>Client for echoStruct operation</h4>
-<pre>void invoke_service_using_databinding ( axis2_stub_t* stub,<br /> const axis2_env_t* env )<br />{<br /> /* variables used by databinding */<br /> axis2_echoStruct_t* echo_in = NULL;<br /> axis2_echoStructResponse_t* echo_out = NULL;<br /> axis2_SOAPStruct_t* struct_in = NULL;<br /> axis2_SOAPStruct_t* struct_out = NULL;<br /><br /><br /> /* variables to store data */<br /> float float_val = 11;<br /> int int_val = 10;<br /> char* string_val = "hello struct";<br /><br /> int ret_int_val = 0;<br /> float ret_float_val = 0;<br /> char* ret_string_val = "";<br /> <br /> /* create the struct and set input values*/<br /> struct_in = axis2_SOAPStruct_create( env );<br /> AXIS2_SOAPSTRUCT_SET_VARFLOAT ( struct_in, env, float_val );<br /> AXIS2_SOAPSTRUCT_SET_VARINT ( struct_in, env, int_val );<br /> AXIS2_SOAPSTRUCT_SET_VARSTRING ( struct_in, env, string_val );<br /><br /> /* create the request and set the struct */<br /> echo_in = axis2_echoStruct_create( env );<br /> AXIS2_EC
 HOSTRUCT_SET_PARAM0( echo_in, env, struct_in );<br /><br /> /* invoke the web service method */<br /> echo_out = axis2_echoStruct( stub, env, echo_in );<br /><br /> /* retrieve the structure from response */<br /> struct_out = AXIS2_ECHOSTRUCTRESPONSE_GET_RETURN( echo_out, env );<br /><br /> /* retrieve each value from the structure */<br /> ret_float_val = AXIS2_SOAPSTRUCT_GET_VARFLOAT ( struct_out, env );<br /> ret_int_val = AXIS2_SOAPSTRUCT_GET_VARINT ( struct_out, env );<br /> ret_string_val = AXIS2_SOAPSTRUCT_GET_VARSTRING ( struct_out, env );<br /><br /> /* print the values */<br /> printf ( "returned values \n");<br /> printf (" float %f\n", ret_float_val );<br /> printf (" int %d \n", ret_int_val );<br /> printf (" string %s \n", ret_string_val);<br /> <br />}</pre>
-<a id="Providing_security_using_Rampart"></a>
-<h2>Providing Security using Rampart/C</h2>
-
-<p>Rampart/C is the security module for Axis2/C, which supports UsernameToken
-based authentication and Timestamps as per WS-Security specification. In this
-User's Guide we will explain how to use Rampart inside Axis2/C.</p>
-
-<h3><a id="Engaging_rampart_module">Engaging rampart module</a></h3>
-<ul>
-  <li><b>Step 1:</b> Copy rampart directory created in
-    AXIS2C_HOME/deploy/rampart to AXIS2C_HOME/deploy/modules
-    <pre class="code">cp $AXIS2C_HOME/deploy/rampart/rampart $AXIS2C_HOME/deploy/modules</pre>
-  </li>
-  <li><b>Step 2:</b>Add following line to the axis2.xml under axisconfig.
-    This will engage the rampart module.
-    <pre class="code">&lt;module ref="rampart"/&gt;</pre>
-  </li>
-  <li><b>Step 3:</b>Then add following to the axis2.xml file to specify
-    In/Out flow parameters. You may find a sample axis2.xml file in
-    rampart/samples/client/echo/data/
-    <pre class="code"> &lt;parameter name="OutflowSecurity"&gt;<br /> &lt;action&gt;<br /> &lt;items&gt;UsernameToken Timestamp&lt;/items&gt;<br /> &lt;user&gt;Gajaba&lt;/user&gt;<br /> &lt;passwordType&gt;passwordDigest&lt;/passwordType&gt;<br /> &lt;passwordCallbackClass&gt;/home/gajaba/axis2/c/deploy/rampart/samples/callback/libpwcb.so&lt;/passwordCallbackClass&gt;<br /> &lt;timeToLive&gt;360&lt;/timeToLive&gt;<br /> &lt;/action&gt;<br /> &lt;/parameter&gt;<br /> </pre>
-    <pre class="code"> &lt;parameter name="InflowSecurity"&gt;<br /> &lt;action&gt;<br /> &lt;items&gt;UsernameToken Timestamp&lt;/items&gt;<br /> &lt;passwordCallbackClass&gt;/home/gajaba/axis2/c/deploy/rampart/samples/callback/libpwcb.so&lt;/passwordCallbackClass&gt;<br /> &lt;/action&gt;<br /> &lt;/parameter&gt;<br /> </pre>
-  </li>
-</ul>
-
-<p><strong>Note:</strong> You must replace the value of
-<code>passwordCallbackClass</code> parameter to suit your settings.</p>
-
-<p>Now everything is setup to try out the sample. Start axis2 server and run
-the sample under rampart/samples/client/echo. If everything works fine a
-security header should be added to the outgoing SOAP message.</p>
-<pre class="code">&lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;<br /> &lt;wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;<br /> &lt;wsse:Username&gt;Gajaba&lt;/wsse:Username&gt;<br /> &lt;wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"&gt;WNPznBN3PeLypKYXlwV7w9zJZ9o=&lt;/wsse:Password&gt;<br /> &lt;wsse:Nonce&gt;ICAgICAgIDEwNDY0NDk1Mg==&lt;/wsse:Nonce&gt;<br /> &lt;wsu:Created&gt;2006-08-28T11:52:27Z&lt;/wsu:Created&gt;<br /> &lt;/wsse:UsernameToken&gt;<br /> &lt;wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;<br /> &lt;wsu:Created&gt;2006-08-28T11:52:27Z&lt;/wsu:Created&gt;<br /> &lt;wsu:Expires&gt;2006-08-28T11:58:27Z&lt;/wsu:Expires&gt;<br /> &lt;/wsu:Timestamp&gt;<br />&lt;/wsse:Security&gt;<br /></
 pre>
-
-<p>Note that for the above sample we have use the same axis2.xml file for
-both server and the client. But in the real world this is not possible. In
-such a situation you can specify a client home as an argument.</p>
-<pre class="code">./echo [endpoint_url] [path to your client_home]</pre>
-
-<h3><a id="Semantics_of_parameters_specified_in_axis2_xml">Semantics of Parameters Specified in axis2.xml</a></h3>
-
-<table border="1" cellpadding="0" cellspacing="0" width="100%">
-  <tbody>
-    <tr>
-      <td><strong>Parameter</strong></td>
-      <td><strong>Semantic</strong></td>
-    </tr>
-    <tr>
-      <td>items</td>
-      <td>Specify which tokens to be used for the credential exchange. In the
-        above example we used both UsernameTokens and Timestamps</td>
-    </tr>
-    <tr>
-      <td>user</td>
-      <td>The username of the UsernameToken</td>
-    </tr>
-    <tr>
-      <td>passwordType</td>
-      <td>The way passowrd is delivered. This can be either passwordText or
-        the passwordDigest. The former delivers password in plainText whilst
-        the latter delivers the hashed value of the password. Default is
-        passwordText</td>
-    </tr>
-    <tr>
-      <td>passwordCallbackClass</td>
-      <td>The module that provides the password for a particular user</td>
-    </tr>
-    <tr>
-      <td>timeToLive</td>
-      <td>The validity period of the TimestampToken after issuing. The time
-        is in seconds. In the above example, it's 6 minutes. If not
-        specified, the default is 5 minutes</td>
-    </tr>
-  </tbody>
-</table>
-<a id="Writing_own_password_callback_module"></a>
-
-<h3>Writing Your Own Password Callback Module</h3>
-
-<p>The Rampart module is independent of the way that passwords are stored.
-For example, you may have passwords in a flat file or in a secured database.
-What ever the way, Rampart expects a password callback module to retrieve
-passwords for a given username. The sample coming under
-"&lt;axis2c_home&gt;rampart/samples/callback" is a very simple one which has
-few hard-coded passwords. It assigns a function to the function pointer</p>
-<pre class="code">rcb-&gt;ops-&gt;callback_password = get_sample_password;</pre>
-
-<p><code>callback_password</code> is a function pointer to any function which
-has the following signature.</p>
-<pre class="code"><code>axis2_char_t</code>* your_function(rampart_callback_t *rcb,<br /> const axis2_env_t *env, const axis2_char_t *username)</pre>
-
-<p><code>your_function</code> should return the password as
-<code>axis2_char_t</code>* for the username specified, if any. Inside your
-function, you may write your code to supply stored passwords.</p>
-
-<p>Then the path to the callback module needs to be specified in axis2.xml
-under passwordCallbackClass. [The word Class, instead of Module is only for
-the compatibility with java implementation]</p>
-<a id="Adding_security_parameters_dynamically"></a>
-
-<h3>Adding Security Parameters Dynamically</h3>
-
-<p>Outflow parameters specified in the axis2.xml can be added dynamically in
-the client level. This can be done as in the following sample code.</p>
-<pre class="code"> un_property = axis2_property_create(env);<br /> AXIS2_PROPERTY_SET_VALUE(un_property, env, "Gajaba");<br /> AXIS2_OPTIONS_SET_PROPERTY(options, env, RAMPART_ACTION_USER, un_property);<br /></pre>
-
-<p>Above will set the username parameter dynamically. All the values
-specified in the axis2.xml will be overridden by the dynamic settings.</p>
-
-<h2>References</h2>
-<ul>
-  <li>Introducing Apache Axis2/C - <a
-    href="http://www.wso2.net/articles/axis2/c/2006/09/04/introduction">http://www.wso2.net/articles/axis2/c/2006/09/04/introduction</a></li>
-  <li>Introducing Rampart/C- <a
-    href="http://www.wso2.net/articles/rampart/c/2006/09/19/introduction">http://www.wso2.net/articles/rampart/c/2006/09/19/introduction</a></li>
-</ul>
-</body>
-</html>
+<?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" />
+  <title>Axis2/C User's Guide</title>
+  <meta name="generator" content="Bluefish 1.0.5"/>
+</head>
+
+<body xml:lang="en">
+<h1>Apache Axis2/C User's Guide</h1>
+
+<h2>Content</h2>
+<ul>
+  <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>
+    <ul>
+      <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>
+            <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 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>
+        <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="#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>
+    <ul>
+      <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="#EchoNonBlockingClient">echo_non_blocking
+          Client</a></li>
+          <li><a href="#EchoNonBlockingDualClient">echo_non_blocking_dual
+            Client</a></li>
+          <li><a href="#EchoBlockingDualClient">echo_blocking_dual
+          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>
+        <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>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <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="#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>
+    </ul>
+  </li>
+</ul>
+
+<a id="Introduction"></a>
+<h2>Introduction</h2>
+
+<p>Welcome to Axis2/C, the Apache Axis2 implementation in C. This User's Guide
+will help you understand what Axis2/C has to offer and how to get started
+with it.</p>
+
+<a id="What_is_Axis2_"></a>
+<h3>What is Axis2/C?</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>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 Java implementation.</p>
+  </li>
+  <li><p style="margin-bottom: 0in;"><strong>Low memory foot print</strong>-
+    Axis2 architecture was designed ground-up keeping in mind the low memory foot
+    print. 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> - Supports
+    Message Exchange Patterns (MEPs)</p>
+  </li>
+  <li><p style="margin-bottom: 0in;"><strong>Flexibility</strong> - 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 support composability and are
+    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>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
+please remember to prefix the subject of the mail with [Axis2].</p>
+
+<p>The following sections will guide on how to write Web service
+clients and services.</p>
+
+<a name="Web_Services_Using_Axis2"></a>
+<h2>Web Services Using Axis2/C</h2>
+
+<p>Before starting, please make sure that you have installed Axis2/C
+correctly and whether you can run the axis2_http_server located in
+AXIS2C_HOME/bin (See <a href="installationguide.html">Installation Guide</a>
+for details).</p>
+
+<a name="Writing_Web_Services_Using_Axis2_C"></a>
+<h3>Writing Web Services Using Axis2/C</h3>
+
+<a id="Creating_Web_Service__MyService_"></a>
+<h4>Creating Web Service (Echo service)</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>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>
+
+<a id="How_to_write_the_Web_Service_"></a>
+<h4>How to write the Web Service?</h4>
+
+<p>Writing a new Web Service with Axis2/C involves 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>
+  <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 into that folder.</li>
+</ol>
+<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
+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>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-&gt;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-&gt;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>        &amp;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-&gt;func_array)</code><br
+/>
+<code>    {</code><br />
+<code>        AXIS2_ARRAY_LIST_FREE(svc_skeleton-&gt;func_array, env);</code><br
+/>
+<code>        svc_skeleton-&gt;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-&gt;ops)</code><br
+/>
+<code>    {</code><br />
+<code>        AXIS2_FREE(env-&gt;allocator, svc_skeleton-&gt;ops);</code><br
+/>
+<code>        svc_skeleton-&gt;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-&gt;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>/*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-&gt;allocator, </code><br />
+<code>        </code><b><code>sizeof</code></b><code>(axis2_svc_skeleton_t));</code><br
+/>
+<br />
+<code>    svc_skeleton-&gt;ops = AXIS2_MALLOC(</code><br />
+<code>        env-&gt;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-&gt;ops-&gt;free = echo_free;</code><br />
+<code>    svc_skeleton-&gt;ops-&gt;init = echo_init;</code><br />
+<code>    svc_skeleton-&gt;ops-&gt;invoke = echo_invoke;</code><br />
+<code>    svc_skeleton-&gt;ops-&gt;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>
+
+<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
+exposing 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 casts 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>     * &lt;ns1:echoString xmlns:ns1="http://localhost:9090/axis2/services/echo"&gt;</code><br
+/>
+<code>     *      &lt;text&gt;echo5&lt;/text&gt;</code><br />
+<code>     * &lt;/ns1:echoString&gt;</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-&gt;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-&gt;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-&gt;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 &amp;&amp; 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-&gt;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, &amp;echo_om_node);</code><br
+/>
+<code>    </code><br />
+<code>    text_om_ele = axiom_element_create(env, echo_om_node, "text", NULL, &amp;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>
+
+<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">&lt;service name="echo"&gt;<br /> &lt;parameter name="ServiceClass" locked="xsd:false"&gt;echo&lt;/parameter&gt;<br /> &lt;description&gt;<br /> This is a echo service<br /> &lt;/description&gt;<br /><br /> &lt;operation name="echoString"&gt;<br /> &lt;parameter name="wsamapping"&gt;<br /> http://localhost:9090/axis2/services/echo/echoString<br /> &lt;/parameter&gt;<br /> &lt;/operation&gt;<br />&lt;/service&gt;</pre>
+
+<p>Name of the service will be the name of the folder with the shared library
+and services.xml. In 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">&lt;serviceGroup&gt;<br /> &lt;service name="Service1"&gt;<br /> &lt;!-- details for Service1 --&gt;<br /> &lt;/service&gt;<br /> &lt;service name="Service2"&gt;<br /> &lt;!-- details for Service2 --&gt;<br /> &lt;/service&gt;<br /> &lt;module ref="ModuleName" /&gt;<br /> &lt;parameter name="serviceGroupParam1" locked="false"&gt;value 1&lt;/parameter&gt;<br />&lt;/serviceGroup&gt;</pre>
+
+<p><strong>Note :</strong> 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>
+
+<a name="Writing_Web_Services_Using_Code_Generator"></a>
+<h3>Writing Web Services Skeleton Using Code Generator</h3>
+
+<a id="WSDL2Code_tool"></a>
+<h4>WSDL2Code tool</h4>
+
+<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 provide 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 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>

[... 446 lines stripped ...]


---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org