<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dimuthu's Blog &#187; axis2/c</title>
	<atom:link href="http://www.dimuthu.org/catagory/axis2c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dimuthu.org</link>
	<description>Waiting for your comments</description>
	<lastBuildDate>Wed, 21 Dec 2011 05:39:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<image>
  <link>http://www.dimuthu.org</link>
  <url>http://www.dimuthu.org/favicon.ico</url>
  <title>Dimuthu's Blog</title>
</image>
		<item>
		<title>Code Generate Custom SOAP Faults For Axis2/C</title>
		<link>http://www.dimuthu.org/blog/2009/02/09/code-generate-custom-soap-faults-for-axis2c/</link>
		<comments>http://www.dimuthu.org/blog/2009/02/09/code-generate-custom-soap-faults-for-axis2c/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 06:04:41 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[2 minutes guide]]></category>
		<category><![CDATA[adb]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[codegen]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[WSDL]]></category>
		<category><![CDATA[wsdl2c]]></category>
		<category><![CDATA[xml schema]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[faults]]></category>
		<category><![CDATA[handling]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[throwing]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=916</guid>
		<description><![CDATA[Web services use SOAP faults to report fault cases back to clients. The faults can be generated from the SOAP framework in a case of invalid SOAP messages, invalid security tokens or they can be generated from the service business logic itself. The fault messages may contain simply a string indicating the error, or it [...]]]></description>
			<content:encoded><![CDATA[<p>Web services use SOAP faults to report fault cases back to clients. The faults can be generated from the SOAP framework in a case of invalid SOAP messages, invalid security tokens or they can be generated from the service business logic itself. The fault messages may contain simply a string indicating the error, or it may contain lot of details which could be useful to the clients find the problem. In fact the format of the SOAP fault is a standard. But services can send custom details within the details element in a SOAP fault.</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;soapenv:Envelope</span> <span style="color: #000066;">xmlns:soapenv</span>=<span style="color: #ff0000;">"http://schemas.xmlsoap.org/soap/envelope/"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;soapenv:Body<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;soapenv:Fault<span style="font-weight: bold; color: black;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;faultcode<span style="font-weight: bold; color: black;">&gt;</span></span></span>soapenv:Sender<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/faultcode<span style="font-weight: bold; color: black;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;faultstring<span style="font-weight: bold; color: black;">&gt;</span></span></span>..<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/faultstring<span style="font-weight: bold; color: black;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;detail<span style="font-weight: bold; color: black;">&gt;</span></span></span> You Custom Message <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/detail<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/soapenv:Fault<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/soapenv:Body<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/soapenv:Envelope<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>And you can define the schema of your custom fault message in a WSDL, so the clients can prepare to handle fault scenarios. In facts tools like <a href="http://ws.apache.org/axis2/">Apache Axis2</a> WSDL2C, WSDL2Java tool will help you to work with custom faults when they are defined in the WSDL.  Here is an example section of a WSDL with an operation which can throw two faults &#8220;MyFirstException&#8221;, &#8220;MySecondException&#8221;.</p>
<pre class="xml"><span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- fault schemas --&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;types<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;schema</span> ..<span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MyFirstException"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
     <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"text"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"xsd:string"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- fault element --&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MySecondException"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
     <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"number"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"xsd:int"</span><span style="color: #ff0000;"></span><span style="font-weight: bold; color: black;">/&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/schema<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/types<span style="font-weight: bold; color: black;">&gt;</span></span></span>

<span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- the fault messages --&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;message</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MySecondExceptionFault"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;part</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"fault"</span> <span style="color: #000066;">element</span>=<span style="color: #ff0000;">"ns1:MySecondException"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/message<span style="font-weight: bold; color: black;">&gt;</span></span></span>

<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;message</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MyFirstExceptionFault"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;part</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"fault"</span> <span style="color: #000066;">element</span>=<span style="color: #ff0000;">"ns1:MyFirstException"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/message<span style="font-weight: bold; color: black;">&gt;</span></span></span>

<span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- operation to throw fault --&gt;</span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;portType</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MyType"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;operation</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"myOperation"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;input</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">"tns:myOperationRequest"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;output</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">"tns:myOperationResponse"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fault</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MySecondException"</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">"tns:MySecondExceptionFault"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fault</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"MyFirstException"</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">"tns:MyFirstExceptionFault"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
 <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/operation<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/portType<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>Note that the operation &#8220;myOperation&#8221; is throwing faults &#8220;MyFirstException&#8221;, &#8220;MySecondExcpetion&#8221;. If you generate the Java code for this operation, it would be simple as this,</p>
<pre class="java"><span style="color: #000000; font-weight: bold;">public</span> MyOperationRequest
MyOperation<span style="color: #66cc66;">(</span>MyOperationRequest<span style="color: #66cc66;">)</span> <span style="color: #000000; font-weight: bold;">throws</span>
          MyFirstExcpetion,
          MySecondExcpetion <span style="color: #66cc66;">{</span>
  <span style="color: #808080; font-style: italic;">// here is your business logic</span>
<span style="color: #66cc66;">}</span></pre>
<p>Anyway we are going to write codes in &#8216;C&#8217; language, which doesn&#8217;t have similar exception mechanism. Let see how we can do it, starting with writing the service and then writing a client.</p>
<p><strong>Writing Services With Custom SOAP Faults</strong></p>
<p>Once you generate the &#8216;C&#8217; codes for the WSDL using WSDL2C tool, you should first have a look at the skeleton header file.</p>
<pre class="c">    <span style="color: #808080; font-style: italic;">/**
     * the generated fault union for operation "myOperation|urn:myuri:1.0",
     * in a case you want to return a fault, put the appropriate adb object for
     * the union variable pointer comes as the last parameter of the method
     */</span>
    <span style="color: #993333;">typedef</span> <span style="color: #993333;">union</span>
    <span style="color: #66cc66;">{</span>
        adb_MyFirstException_t* MyFirstException;
        adb_MySecondException_t* MySecondException;

    <span style="color: #66cc66;">}</span> axis2_skel_MyService_myOperation_fault;

    <span style="color: #808080; font-style: italic;">/**
     * auto generated function declaration
     * for "myOperation|urn:myuri:1.0" operation.
     * @param env environment ( mandatory)
     * @param _myOperation of the adb_myOperation_t*
     *
     * @return adb_myOperationResponse_t*
     */</span>
    adb_myOperationResponse_t* axis2_skel_MyService_myOperation<span style="color: #66cc66;">(</span><span style="color: #993333;">const</span> axutil_env_t *env,
                                      adb_myOperation_t* _myOperation,
                                      axis2_skel_MyService_myOperation_fault *fault<span style="color: #66cc66;">)</span>;</pre>
<p>And at the very end of the header file, you will see an enumeration of constants corresponding to each fault is generated.</p>
<pre class="c">    <span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span>
    <span style="color: #66cc66;">{</span>
        AXIS2_SKEL_MYSERVICE_ERROR_NONE = AXIS2_SKEL_MYSERVICE_ERROR_CODES_START,

        AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION,
        AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION,

        AXIS2_SKEL_MYSERVICE_ERROR_LAST

    <span style="color: #66cc66;">}</span> axis2_skel_MyService_error_codes;</pre>
<p>That&#8217;s all you need to aware of. The plan is whenever you need to report the fault, you have to do three things inside the business logic.</p>
<ol>
<li>Create the adb object for the fault, in this case either &#8220;adb_MyFirstException_t&#8221; or &#8220;adb_MySecondException_t&#8221; and set it to the fault pointer variable.</li>
<li>Set the constant corresponding to the fault using &#8220;AXIS2_ERROR_SET&#8221; function</li>
<li>return NULL</li>
</ol>
<p>Here is an example how you do it inside the actual business logic code.</p>
<pre class="c">    adb_myOperationResponse_t* axis2_skel_MyService_myOperation<span style="color: #66cc66;">(</span><span style="color: #993333;">const</span> axutil_env_t *env,
                                      adb_myOperation_t* myOperation,
                                      axis2_skel_MyService_myOperation_fault *fault <span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        <span style="color: #808080; font-style: italic;">/* the buisness logic */</span>

        ....

        <span style="color: #b1b100;">if</span><span style="color: #66cc66;">(</span><span style="color: #808080; font-style: italic;">/* checking some condition to throw the "MyFirstException" fault */</span><span style="color: #66cc66;">)</span>
        <span style="color: #66cc66;">{</span>
          <span style="color: #808080; font-style: italic;">/* 1. Creating the adb object and set it to the fault pointer variable */</span>
          adb_MyFirstException_t *exp = <span style="color: #000000; font-weight: bold;">NULL</span>;
          exp = adb_MyFirstException_create<span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>;
          adb_MyFirstException_set_text<span style="color: #66cc66;">(</span>exp, env, <span style="color: #ff0000;">"this is the exception 1"</span><span style="color: #66cc66;">)</span>; <span style="color: #808080; font-style: italic;">/* custom value */</span>

          fault-&gt;MyFirstException = exp;

          <span style="color: #808080; font-style: italic;">/* 2. Setting the error constant corrosponding to the fault */</span>
          AXIS2_ERROR_SET<span style="color: #66cc66;">(</span>env-&gt;error,
                      AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION,
                      AXIS2_FAILURE<span style="color: #66cc66;">)</span>;

          <span style="color: #808080; font-style: italic;">/* 3. Returning NULL */</span>
          <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">NULL</span>;
        <span style="color: #66cc66;">}</span>

        <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #66cc66;">(</span><span style="color: #808080; font-style: italic;">/* checking some condition to throw the "MySecondException" fault */</span><span style="color: #66cc66;">)</span>
        <span style="color: #66cc66;">{</span>
          <span style="color: #808080; font-style: italic;">/* 1. Creating the adb object and set it to the fault pointer variable */</span>
          adb_MySecondException_t *exp = <span style="color: #000000; font-weight: bold;">NULL</span>;
          exp = adb_MySecondException_create<span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>;
          adb_MySecondException_set_number<span style="color: #66cc66;">(</span>exp, env, <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">)</span>;<span style="color: #808080; font-style: italic;">/* custom value */</span>

          fault-&gt;MySecondException = exp;

          <span style="color: #808080; font-style: italic;">/* 2. Setting the error constant corrosponding to the fault */</span>
          AXIS2_ERROR_SET<span style="color: #66cc66;">(</span>env-&gt;error,
                      AXIS2_SKEL_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION,
                      AXIS2_FAILURE<span style="color: #66cc66;">)</span>;
          <span style="color: #808080; font-style: italic;">/* 3. Returning NULL */</span>
          <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">NULL</span>;
        <span style="color: #66cc66;">}</span>

        <span style="color: #808080; font-style: italic;">/* return the response in no fault scenario */</span>
        <span style="color: #b1b100;">return</span> response;
    <span style="color: #66cc66;">}</span></pre>
<p>That&#8217;s all you have to do, Axis2/C will make sure to build the fault and put your custom message inside the details element.</p>
<p><strong>Writing Clients  to Handle custom SOAP Faults</strong></p>
<p>After generating the code for clients using WSDL2C tool, this time you should look at the generated stub header file first. It is just similar to the skeleton header files may be except all the &#8220;skel&#8221; prefixes are renamed to &#8220;stub&#8221; and additional parameter &#8220;stub&#8221; for the operation.</p>
<pre class="c">    <span style="color: #808080; font-style: italic;">/**
     * the generated fault union for operation "myOperation|urn:myuri:1.0",
     * in a case the server return a fault, the corresponding adb object will be loaded for
     * the union variable pointer comes as the last parameter of the method
     */</span>
    <span style="color: #993333;">typedef</span> <span style="color: #993333;">union</span>
    <span style="color: #66cc66;">{</span>
        adb_MyFirstException_t* MyFirstException;
        adb_MySecondException_t* MySecondException;

    <span style="color: #66cc66;">}</span> axis2_stub_MyService_myOperation_fault;

    <span style="color: #808080; font-style: italic;">/**
     * auto generated function declaration
     * for "myOperation|urn:myuri:1.0" operation.
     * @param env environment ( mandatory)
     * @param _myOperation of the adb_myOperation_t*
     *
     * @return adb_myOperationResponse_t*
     */</span>
    adb_myOperationResponse_t* axis2_stub_MyService_myOperation<span style="color: #66cc66;">(</span>axis2_stub_t* stub, <span style="color: #993333;">const</span> axutil_env_t *env,
                                      adb_myOperation_t* _myOperation,
                                      axis2_stub_MyService_myOperation_fault *fault<span style="color: #66cc66;">)</span>;

    <span style="color: #993333;">typedef</span> <span style="color: #000000; font-weight: bold;">enum</span>
    <span style="color: #66cc66;">{</span>
        AXIS2_STUB_MYSERVICE_ERROR_NONE = AXIS2_STUB_MYSERVICE_ERROR_CODES_START,

        AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION,
        AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION,

        AXIS2_STUB_MYSERVICE_ERROR_LAST

    <span style="color: #66cc66;">}</span> axis2_stub_MyService_error_codes;</pre>
<p>Looking at this, you may have got the idea how to differentiate what fault is being thrown by the server and how to extract the parameters of the custom fault. Here is an example client code correctly handling exceptions.</p>
<pre class="c">    <span style="color: #808080; font-style: italic;">/* the structure to keep the fault */</span>
    axis2_stub_MyService_myOperation_fault fault;

    ..... <span style="color: #808080; font-style: italic;">/* the part preparing the request is ignored here */</span>

    <span style="color: #808080; font-style: italic;">/* invoking the "myOperation" operation */</span>
    response = axis2_stub_op_MyService_myOperation<span style="color: #66cc66;">(</span>stub, env, op, &amp;fault<span style="color: #66cc66;">)</span>;

    <span style="color: #808080; font-style: italic;">/* checking the response == NULL implies fault is sent  */</span>
    <span style="color: #b1b100;">if</span><span style="color: #66cc66;">(</span>response == <span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        <span style="color: #808080; font-style: italic;">/* getting the error number to distinguish the fault */</span>
        error_code = env-&gt;error-&gt;error_number;

        <span style="color: #808080; font-style: italic;">/* compare error code with constants of each faults */</span>
        <span style="color: #b1b100;">if</span><span style="color: #66cc66;">(</span>error_code == AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYFIRSTEXCEPTION<span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>

            <span style="color: #808080; font-style: italic;">/* extracting out the adb objects */</span>
            axis2_char_t *text = adb_MyFirstException_get_text<span style="color: #66cc66;">(</span>fault.<span style="color: #202020;">MyFirstException</span>, env<span style="color: #66cc66;">)</span>;

            <span style="color: #808080; font-style: italic;">/* do a printf of the message */</span>
            <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"My First Exception called: with param %s<span style="color: #000099; font-weight: bold;">\\</span>n"</span>, text<span style="color: #66cc66;">)</span>;

        <span style="color: #66cc66;">}</span>
        <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #66cc66;">(</span>error_code == AXIS2_STUB_MYSERVICE_MYOPERATION_FAULT_MYSECONDEXCEPTION<span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>
            <span style="color: #808080; font-style: italic;">/* extracting out the adb objects */</span>
            <span style="color: #993333;">int</span> number = adb_MySecondException_get_number<span style="color: #66cc66;">(</span>fault.<span style="color: #202020;">MySecondException</span>, env<span style="color: #66cc66;">)</span>;

            <span style="color: #808080; font-style: italic;">/* do a printf of the message */</span>
            <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"My Second Exception called: with param %d<span style="color: #000099; font-weight: bold;">\\</span>n"</span>, number<span style="color: #66cc66;">)</span>;

        <span style="color: #66cc66;">}</span>

    <span style="color: #66cc66;">}</span></pre>
<p>Note that this feature is available only in the very latest WSDL2C tool. Try to get latest build from <a href="http://ws.apache.org/axis2">Axis2/Java</a> to use this up to date tool.</p>
<p>You can download the WSDL and codes used in this example from here, <a href="https://issues.apache.org/jira/secure/attachment/12399724/case45.zip">https://issues.apache.org/jira/secure/attachment/12399724/case45.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2009/02/09/code-generate-custom-soap-faults-for-axis2c/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Hello World To Web Services With C And C++</title>
		<link>http://www.dimuthu.org/blog/2009/01/22/hello-world-to-web-services-with-c-and-c/</link>
		<comments>http://www.dimuthu.org/blog/2009/01/22/hello-world-to-web-services-with-c-and-c/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 04:39:27 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[axiom]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[wsf/c++]]></category>
		<category><![CDATA[wso2]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[hello world]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[wsf/cpp]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=903</guid>
		<description><![CDATA[Once you have a web service, you can write clients to invoke that service from any language, mostly with the help of a framework written in to that particular language. When it comes to C, the most popular choice is Apache Axis2/C framework. When you are using Axis2/C to write web service clients, you need [...]]]></description>
			<content:encoded><![CDATA[<p>Once you have a web service, you can write clients to invoke that service from any language, mostly with the help of a framework written in to that particular language. When it comes to C, the most popular choice is <a href="http://ws.apache.org/axis2/c/">Apache Axis2/C</a> framework. When you are using Axis2/C to write web service clients, you need to learn about AXIOM which is a easy to use high performing XML model and the service client API which can be used to actually invoke the service. Lets look at the code.</p>
<pre class="c"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;axiom.h&gt;</span>
<span style="color: #339933;">#include &lt;axis2_util.h&gt;</span>
<span style="color: #339933;">#include &lt;axiom_soap.h&gt;</span>
<span style="color: #339933;">#include &lt;axis2_client.h&gt;</span>

axiom_node_t *build_om_payload_for_helloworld_svc<span style="color: #66cc66;">(</span>
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>;

<span style="color: #993333;">int</span>
main<span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
    <span style="color: #993333;">const</span> axutil_env_t *env = <span style="color: #000000; font-weight: bold;">NULL</span>;
    <span style="color: #993333;">const</span> axis2_char_t *address = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axis2_endpoint_ref_t *endpoint_ref = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axis2_options_t *options = <span style="color: #000000; font-weight: bold;">NULL</span>;
    <span style="color: #993333;">const</span> axis2_char_t *client_home = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axis2_svc_client_t *svc_client = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axiom_node_t *payload = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axiom_node_t *ret_node = <span style="color: #000000; font-weight: bold;">NULL</span>;

    <span style="color: #808080; font-style: italic;">/* Set up the environment */</span>
    env = axutil_env_create_all<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"helloworld.log"</span>, AXIS2_LOG_LEVEL_TRACE<span style="color: #66cc66;">)</span>;

    <span style="color: #808080; font-style: italic;">/* Set end point reference of helloworld service */</span>
    address = <span style="color: #ff0000;">"http://localhost:9090/axis2/services/helloworld"</span>;

    <span style="color: #808080; font-style: italic;">/* Create EPR with given address */</span>
    endpoint_ref = axis2_endpoint_ref_create<span style="color: #66cc66;">(</span>env, address<span style="color: #66cc66;">)</span>;

    <span style="color: #808080; font-style: italic;">/* Setup options */</span>
    options = axis2_options_create<span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>;
    axis2_options_set_to<span style="color: #66cc66;">(</span>options, env, endpoint_ref<span style="color: #66cc66;">)</span>;
    axis2_options_set_action<span style="color: #66cc66;">(</span>options, env,
                             <span style="color: #ff0000;">"http://ws.apache.org/axis2/c/samples/helloworldString"</span><span style="color: #66cc66;">)</span>;

    <span style="color: #808080; font-style: italic;">/* Set up deploy folder. It is from the deploy folder, the configuration is picked up
     * using the axis2.xml file. You need to set the AXIS2C_HOME variable to the axis2/c
     * installed dir.
     */</span>
    client_home = AXIS2_GETENV<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"AXIS2C_HOME"</span><span style="color: #66cc66;">)</span>;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!client_home || !strcmp<span style="color: #66cc66;">(</span>client_home, <span style="color: #ff0000;">""</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
        client_home = <span style="color: #ff0000;">"../.."</span>;

    <span style="color: #808080; font-style: italic;">/* Create service client */</span>
    svc_client = axis2_svc_client_create<span style="color: #66cc66;">(</span>env, client_home<span style="color: #66cc66;">)</span>;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!svc_client<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        <span style="color: #808080; font-style: italic;">/* reporting the error */</span>
        <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a>
            <span style="color: #66cc66;">(</span><span style="color: #ff0000;">"Error creating service client, Please check AXIS2C_HOME again<span style="color: #000099; font-weight: bold;">\\</span>n"</span><span style="color: #66cc66;">)</span>;
        AXIS2_LOG_ERROR<span style="color: #66cc66;">(</span>env-&gt;log, AXIS2_LOG_SI,
                        <span style="color: #ff0000;">"Stub invoke FAILED: Error code:"</span> <span style="color: #ff0000;">" %d :: %s"</span>,
                        env-&gt;error-&gt;error_number,
                        AXIS2_ERROR_GET_MESSAGE<span style="color: #66cc66;">(</span>env-&gt;error<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
        <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">-1</span>;
    <span style="color: #66cc66;">}</span>

    <span style="color: #808080; font-style: italic;">/* Set service client options */</span>
    axis2_svc_client_set_options<span style="color: #66cc66;">(</span>svc_client, env, options<span style="color: #66cc66;">)</span>;

    <span style="color: #808080; font-style: italic;">/* Build the SOAP request message payload using OM API. */</span>
    payload = build_om_payload_for_helloworld_svc<span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>;

    <span style="color: #808080; font-style: italic;">/* Send request */</span>
    ret_node = axis2_svc_client_send_receive<span style="color: #66cc66;">(</span>svc_client, env, payload<span style="color: #66cc66;">)</span>;

    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>ret_node<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        <span style="color: #808080; font-style: italic;">/* extracting out the content from the response */</span>
        axis2_char_t *om_str = <span style="color: #000000; font-weight: bold;">NULL</span>;
        om_str = axiom_node_to_string<span style="color: #66cc66;">(</span>ret_node, env<span style="color: #66cc66;">)</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>om_str<span style="color: #66cc66;">)</span>
            <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"<span style="color: #000099; font-weight: bold;">\\</span>nReceived OM : %s<span style="color: #000099; font-weight: bold;">\\</span>n"</span>, om_str<span style="color: #66cc66;">)</span>;
        <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"<span style="color: #000099; font-weight: bold;">\\</span>nhelloworld client invoke SUCCESSFUL!<span style="color: #000099; font-weight: bold;">\\</span>n"</span><span style="color: #66cc66;">)</span>;

        AXIS2_FREE<span style="color: #66cc66;">(</span>env-&gt;allocator, om_str<span style="color: #66cc66;">)</span>;
        ret_node = <span style="color: #000000; font-weight: bold;">NULL</span>;
    <span style="color: #66cc66;">}</span>
    <span style="color: #b1b100;">else</span>
    <span style="color: #66cc66;">{</span>
        AXIS2_LOG_ERROR<span style="color: #66cc66;">(</span>env-&gt;log, AXIS2_LOG_SI,
                        <span style="color: #ff0000;">"Stub invoke FAILED: Error code:"</span> <span style="color: #ff0000;">" %d :: %s"</span>,
                        env-&gt;error-&gt;error_number,
                        AXIS2_ERROR_GET_MESSAGE<span style="color: #66cc66;">(</span>env-&gt;error<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;
        <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"helloworld client invoke FAILED!<span style="color: #000099; font-weight: bold;">\\</span>n"</span><span style="color: #66cc66;">)</span>;
    <span style="color: #66cc66;">}</span>

    <span style="color: #808080; font-style: italic;">/* freeing the allocated memory */</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>svc_client<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        axis2_svc_client_free<span style="color: #66cc66;">(</span>svc_client, env<span style="color: #66cc66;">)</span>;
        svc_client = <span style="color: #000000; font-weight: bold;">NULL</span>;
    <span style="color: #66cc66;">}</span>

    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        axutil_env_free<span style="color: #66cc66;">(</span><span style="color: #66cc66;">(</span>axutil_env_t *<span style="color: #66cc66;">)</span> env<span style="color: #66cc66;">)</span>;
        env = <span style="color: #000000; font-weight: bold;">NULL</span>;
    <span style="color: #66cc66;">}</span>

    <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span>;
<span style="color: #66cc66;">}</span></pre>
<p>Here is the implementation of the &#8220;build_om_payload_for_helloworld_svc&#8221; function that build the request SOAP message using Axiom/C. Note that axiom_element and axiom_node has one to one association. We use node to to navigate the XML, where as axiom_element to store the data.</p>
<pre class="c"><span style="color: #808080; font-style: italic;">/* build SOAP request message content using OM
           &lt;ns1:greet xmlns:ns1="http://ws.apache.org/axis2/services/helloworld"&gt;
                &lt;text&gt;Hello World&lt;/text&gt;
           &lt;/ns1:greet&gt;
*/</span>
axiom_node_t *
build_om_payload_for_helloworld_svc<span style="color: #66cc66;">(</span>
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
    axiom_node_t *helloworld_om_node = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axiom_element_t *helloworld_om_ele = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axiom_node_t *text_om_node = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axiom_element_t *text_om_ele = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axiom_namespace_t *ns1 = <span style="color: #000000; font-weight: bold;">NULL</span>;
    axis2_char_t *om_str = <span style="color: #000000; font-weight: bold;">NULL</span>;

    ns1 =
       axiom_namespace_create<span style="color: #66cc66;">(</span>env, <span style="color: #ff0000;">"http://ws.apache.org/axis2/services/helloworld"</span>,
                               <span style="color: #ff0000;">"ns1"</span><span style="color: #66cc66;">)</span>;
    helloworld_om_ele =
        axiom_element_create<span style="color: #66cc66;">(</span>env, <span style="color: #000000; font-weight: bold;">NULL</span>, <span style="color: #ff0000;">"greet"</span>, ns1, &amp;helloworld_om_node<span style="color: #66cc66;">)</span>;
    text_om_ele =
        axiom_element_create<span style="color: #66cc66;">(</span>env, helloworld_om_node, <span style="color: #ff0000;">"text"</span>, <span style="color: #000000; font-weight: bold;">NULL</span>, &amp;text_om_node<span style="color: #66cc66;">)</span>;
    axiom_element_set_text<span style="color: #66cc66;">(</span>text_om_ele, env, <span style="color: #ff0000;">"Hello World!"</span>, text_om_node<span style="color: #66cc66;">)</span>;
    om_str = axiom_node_to_string<span style="color: #66cc66;">(</span>helloworld_om_node, env<span style="color: #66cc66;">)</span>;

    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>om_str<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"<span style="color: #000099; font-weight: bold;">\\</span>nSending OM : %s<span style="color: #000099; font-weight: bold;">\\</span>n"</span>, om_str<span style="color: #66cc66;">)</span>;
        AXIS2_FREE<span style="color: #66cc66;">(</span>env-&gt;allocator, om_str<span style="color: #66cc66;">)</span>;
        om_str = <span style="color: #000000; font-weight: bold;">NULL</span>;
    <span style="color: #66cc66;">}</span>
    <span style="color: #b1b100;">return</span> helloworld_om_node;
<span style="color: #66cc66;">}</span></pre>
<p>So lets see how the same thing is done with C++. For C++ we use <a href="http://wso2.org/projects/wsf/cpp">WSO2 WSF/C++</a></p>
<pre class="cpp"><span style="color: #339900;">#include &lt;stdio.h&gt;</span>
<span style="color: #339900;">#include &lt;WSSOAPClient.h&gt;</span>
<span style="color: #339900;">#include &lt;OMElement.h&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;AxisFault.h&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> wso2wsf;

OMElement build_om_payload_for_helloworld_svc<span style="color: #000000;">(</span><span style="color: #000000;">)</span>;

<span style="color: #0000ff;">int</span> main<span style="color: #000000;">(</span><span style="color: #000000;">)</span>
<span style="color: #000000;">{</span>
    WSSOAPClient * sc = <span style="color: #0000dd;">new</span> WSSOAPClient<span style="color: #000000;">(</span><span style="color: #666666;">"http://localhost:9090/axis2/services/helloworld"</span><span style="color: #000000;">)</span>;
    sc-&gt;initializeClient<span style="color: #000000;">(</span><span style="color: #666666;">"helloworld_blocking.log"</span>, AXIS2_LOG_LEVEL_TRACE<span style="color: #000000;">)</span>;
    <span style="color: #000000;">{</span>
        <span style="color: #ff0000; font-style: italic;">/* generating the payload */</span>
        OMElement * payload = build_om_payload_for_helloworld_svc<span style="color: #000000;">(</span><span style="color: #000000;">)</span>;

        OMElement * response;
        <span style="color: #0000ff;">try</span>
        <span style="color: #000000;">{</span>
            <span style="color: #ff0000; font-style: italic;">/* invoking the web service */</span>
            response = sc-&gt;request<span style="color: #000000;">(</span>payload, <span style="color: #666666;">"http://ws.apache.org/axis2/c/samples/helloworldString"</span><span style="color: #000000;">)</span>;

            <span style="color: #ff0000; font-style: italic;">/* printing the response */</span>
            <span style="color: #0000ff;">if</span> <span style="color: #000000;">(</span>response<span style="color: #000000;">)</span>
            <span style="color: #000000;">{</span>
                <span style="color: #0000dd;">cout</span> &lt;&lt; endl &lt;&lt; <span style="color: #666666;">"Response: "</span> &lt;&lt; response &lt;&lt; endl;
            <span style="color: #000000;">}</span>
        <span style="color: #000000;">}</span>

        <span style="color: #ff0000; font-style: italic;">/* handling the fault */</span>
        <span style="color: #0000ff;">catch</span> <span style="color: #000000;">(</span>AxisFault &amp; e<span style="color: #000000;">)</span>
        <span style="color: #000000;">{</span>
            <span style="color: #0000ff;">if</span> <span style="color: #000000;">(</span>sc-&gt;getLastSOAPFault<span style="color: #000000;">(</span><span style="color: #000000;">)</span><span style="color: #000000;">)</span>
            <span style="color: #000000;">{</span>
                <span style="color: #0000dd;">cout</span> &lt;&lt; endl &lt;&lt; <span style="color: #666666;">"Response: "</span> &lt;&lt; sc-&gt;getLastSOAPFault<span style="color: #000000;">(</span><span style="color: #000000;">)</span> &lt;&lt; endl;
            <span style="color: #000000;">}</span>
            <span style="color: #0000ff;">else</span>
            <span style="color: #000000;">{</span>
                <span style="color: #0000dd;">cout</span> &lt;&lt; endl &lt;&lt; <span style="color: #666666;">"Response: "</span> &lt;&lt; e &lt;&lt; endl;
            <span style="color: #000000;">}</span>
        <span style="color: #000000;">}</span>
        <span style="color: #0000dd;">delete</span> payload;
    <span style="color: #000000;">}</span>
    <span style="color: #0000dd;">delete</span> sc;
<span style="color: #000000;">}</span></pre>
<p>You can see lines of code is reduced a lot. And you can see it from the code to build the request XML as well.</p>
<pre class="cpp"><span style="color: #ff0000; font-style: italic;">/* building the request soap message
   &lt;ns1:greet xmlns:ns1="http://ws.apache.org/axis2/services/helloworld"&gt;
        &lt;text&gt;Hello World&lt;/text&gt;
   &lt;/ns1:greet&gt;
 */</span>
OMElement build_om_payload_for_helloworld_svc<span style="color: #000000;">(</span><span style="color: #000000;">)</span>
<span style="color: #000000;">{</span>
    OMNamespace * ns = <span style="color: #0000dd;">new</span> OMNamespace<span style="color: #000000;">(</span><span style="color: #666666;">"http://ws.apache.org/axis2/services/helloworld"</span>, <span style="color: #666666;">"ns1"</span><span style="color: #000000;">)</span>;
    OMElement * payload = <span style="color: #0000dd;">new</span> OMElement<span style="color: #000000;">(</span><span style="color: #0000ff;">NULL</span>,<span style="color: #666666;">"greet"</span>, ns<span style="color: #000000;">)</span>;
    OMElement * child = <span style="color: #0000dd;">new</span> OMElement<span style="color: #000000;">(</span>payload,<span style="color: #666666;">"text"</span>, <span style="color: #0000ff;">NULL</span><span style="color: #000000;">)</span>;
    child-&gt;setText<span style="color: #000000;">(</span><span style="color: #666666;">"Hello World!"</span><span style="color: #000000;">)</span>;

    <span style="color: #0000ff;">return</span> payload;
<span style="color: #000000;">}</span></pre>
<p>WSF/C++ is build on top of Axis2/C. You can see the WSF/C++ API is designed very carefully to make it easy to use without breaking the flexibility provided in the C API. So C++ developers can straightaway use WSF/C++ to develop their web service consumers. Anyway Axis2/C API still has the power of embedding easily in to scripting languages  (Like it is done in WSF/PHP, WSF/Ruby) and probably deploy in legacy systems that doesn&#8217;t support C++ compiled binaries. So you have the options to select the most sutiable one for your application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2009/01/22/hello-world-to-web-services-with-c-and-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using AXIOM/C As The XML Object Model</title>
		<link>http://www.dimuthu.org/blog/2008/12/03/using-axiomc-as-the-xml-object-model/</link>
		<comments>http://www.dimuthu.org/blog/2008/12/03/using-axiomc-as-the-xml-object-model/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 16:35:04 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[axiom]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[DataServices]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[AXIOM/C]]></category>
		<category><![CDATA[axiom_node_t*]]></category>
		<category><![CDATA[Buffer]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=754</guid>
		<description><![CDATA[In Apache Axis2/C AXIOM is used as the basic object model to represent XML. AXIOM provide a DOM like API that allows to traverse and build the XML very easily. Anyway in underneath, AXIOM is different from DOM, as it has used some techniques to optimize the parsing of the XML as suited specially for [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://ws.apache.org/axis2/c/">Apache Axis2/C</a> AXIOM is used as the basic object model to represent XML. AXIOM provide a DOM like API that allows to traverse and build the XML very easily.</p>
<p>Anyway in underneath, AXIOM is different from DOM, as it has used some techniques to optimize the parsing of the XML as suited specially for SOAP message processing in web services. For an example the SOAP processor can validate a SOAP message by reading only some parts of the SOAP header fields, and if it is not valid, they can completely skip processing the body part. And since AXIOM is designed to built from a stream of data retrieved from a transport, sometimes SOAP processors can validate the message without the need of reading the full stream.</p>
<p>Anyway there should be lot of application that needs this optimization in parsing XMLs. They can easily adapt AXIOM/C to their application. Here is an <a href="http://ws.apache.org/axis2/c/docs/om_tutorial.html">AXIOM/C tutorial</a> that covers both parsing and building XMLs from AXIOM. In this post I&#8217;d like to mention a code that can be used to retrieve an AXIOM from a String (char buffer) which we call as deserialization.</p>
<pre class="c">    axiom_node_t* AXIS2_CALL
    deserialize_my_buffer <span style="color: #66cc66;">(</span>
        <span style="color: #993333;">const</span> axutil_env_t * env,
        <span style="color: #993333;">char</span> *buffer<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        axiom_xml_reader_t *reader = <span style="font-weight: bold; color: #000000;">NULL</span>;
        axiom_stax_builder_t *builder = <span style="font-weight: bold; color: #000000;">NULL</span>;
        axiom_document_t *document = <span style="font-weight: bold; color: #000000;">NULL</span>;
        axiom_node_t *payload = <span style="font-weight: bold; color: #000000;">NULL</span>;

        reader = axiom_xml_reader_create_for_memory <span style="color: #66cc66;">(</span>env,
            buffer, axutil_strlen <span style="color: #66cc66;">(</span>buffer<span style="color: #66cc66;">)</span>,
            AXIS2_UTF_8, AXIS2_XML_PARSER_TYPE_BUFFER<span style="color: #66cc66;">)</span>;

        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!reader<span style="color: #66cc66;">)</span>
        <span style="color: #66cc66;">{</span>
            <span style="color: #b1b100;">return</span> <span style="font-weight: bold; color: #000000;">NULL</span>;
        <span style="color: #66cc66;">}</span>

        builder = axiom_stax_builder_create <span style="color: #66cc66;">(</span>env, reader<span style="color: #66cc66;">)</span>;

        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!builder<span style="color: #66cc66;">)</span>
        <span style="color: #66cc66;">{</span>
            <span style="color: #b1b100;">return</span> <span style="font-weight: bold; color: #000000;">NULL</span>;
        <span style="color: #66cc66;">}</span>
        document = axiom_stax_builder_get_document <span style="color: #66cc66;">(</span>builder, env<span style="color: #66cc66;">)</span>;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!document<span style="color: #66cc66;">)</span>
        <span style="color: #66cc66;">{</span>
            AXIS2_LOG_ERROR <span style="color: #66cc66;">(</span>env-&gt;log, AXIS2_LOG_SI,
                    <span style="color: #ff0000;">"Document is null for deserialization"</span><span style="color: #66cc66;">)</span>;
            <span style="color: #b1b100;">return</span> <span style="font-weight: bold; color: #000000;">NULL</span>;
        <span style="color: #66cc66;">}</span>

        payload = axiom_document_get_root_element <span style="color: #66cc66;">(</span>document, env<span style="color: #66cc66;">)</span>;

        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!payload<span style="color: #66cc66;">)</span>
        <span style="color: #66cc66;">{</span>
            AXIS2_LOG_ERROR <span style="color: #66cc66;">(</span>env-&gt;log, AXIS2_LOG_SI,
                    <span style="color: #ff0000;">"Root element of the document is not found"</span><span style="color: #66cc66;">)</span>;
            <span style="color: #b1b100;">return</span> <span style="font-weight: bold; color: #000000;">NULL</span>;
        <span style="color: #66cc66;">}</span>
        axiom_document_build_all <span style="color: #66cc66;">(</span>document, env<span style="color: #66cc66;">)</span>;

        axiom_stax_builder_free_self <span style="color: #66cc66;">(</span>builder, env<span style="color: #66cc66;">)</span>;

        <span style="color: #b1b100;">return</span> payload;
    <span style="color: #66cc66;">}</span></pre>
<p>Regardless of the fact this piece of code is been used many time by Axis2 and application that uses Axis2, it has never been identified as a core AXIOM function. I think it is better we have this function as an alternative method to create an axiom.</p>
<pre class="c">axiom_node_t *AXIS2_CALL
axiom_node_create_from_buffer<span style="color: #66cc66;">(</span><span style="color: #993333;">const</span> axutil_env_t *env, axis2_char_t *buffer<span style="color: #66cc66;">)</span>;</pre>
<p>I already suggested this in Axis2/C mailing list and hopefully it will be included from the next release.</p>
<p>Here when we create the axiom tree function from the character buffer, we used &#8220;axiom_xml_reader_create_for_memory&#8221; function. Anyway whenever transport read data stream from wire it always uses the &#8220;axiom_xml_reader_create_for_io&#8221; function.</p>
<pre class="c">    <span style="font-style: italic; color: #808080;">/**
     * This create an instance of axiom_xml_reader to
     * parse a xml document in a buffer. It takes a callback
     * function that takes a buffer and the size of the buffer
     * The user must implement a function that takes in buffer
     * and size and fill the buffer with specified size
     * with xml stream, parser will call this function to fill the
     * buffer on the fly while parsing.
     * @param env environment MUST NOT be NULL.
     * @param read_input_callback() callback function that fills
     * a char buffer.
     * @param close_input_callback() callback function that closes
     * the input stream.
     * @param ctx, context can be any data that needs to be passed
     * to the callback method.
     * @param encoding encoding scheme of the xml stream
     */</span>
    AXIS2_EXTERN axiom_xml_reader_t *AXIS2_CALL
    axiom_xml_reader_create_for_io<span style="color: #66cc66;">(</span>
        <span style="color: #993333;">const</span> axutil_env_t * env,
        AXIS2_READ_INPUT_CALLBACK read_callback,
        AXIS2_CLOSE_INPUT_CALLBACK close_callback,
        <span style="color: #993333;">void</span> *ctx,
        <span style="color: #993333;">const</span> axis2_char_t * encoding<span style="color: #66cc66;">)</span>;</pre>
<p>As you may have noticed it requires us to implement a &#8220;read_callback&#8221; function. Here is an example function prototype to implement this callback.</p>
<pre class="c">    <span style="color: #993333;">int</span> AXIS2_CALL
    some_function<span style="color: #66cc66;">(</span>
            <span style="color: #993333;">char</span> *buffer,
            <span style="color: #993333;">int</span> size,
            <span style="color: #993333;">void</span> *ctx<span style="color: #66cc66;">)</span>;</pre>
<p>This function will be called by the parser as required to parse the XML read from some stream.</p>
<p>So if your application involves reading data from a stream you are always recommended to use this function (i.e. &#8220;axiom_xml_reader_create_for_io&#8221;) instead of &#8220;axiom_xml_read_create_for_buffer&#8221; to create the AXIOM model more effectively.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/12/03/using-axiomc-as-the-xml-object-model/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sending Binary with Apache Axis2/C ADB</title>
		<link>http://www.dimuthu.org/blog/2008/11/24/sending-binary-with-apache-axis2c-adb/</link>
		<comments>http://www.dimuthu.org/blog/2008/11/24/sending-binary-with-apache-axis2c-adb/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 18:21:22 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[adb]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[codegen]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[wsdl2c]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xml schema]]></category>
		<category><![CDATA[base64 binary]]></category>
		<category><![CDATA[binary]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=716</guid>
		<description><![CDATA[Axis2/C ADB is a C language binding to the XML schema. ADB object model represents an XML specific to a given schema in a WSDL. You can use the Axis2 codegen tool to generate ADB codes for your WSDL and use that to build and parse your XMLs. The idea is, if you use ADB [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ws.apache.org/axis2/c/">Axis2/C</a> ADB  is a C language binding to the XML schema. ADB object model represents an  XML specific to a given schema in a WSDL. You can use the Axis2 codegen tool to generate ADB codes for your WSDL and use that to build and parse your XMLs. The idea is, if you use ADB to build and parse your xmls, it will be really easy to do that  and you don&#8217;t need to know or understand anything about the schema or the wsdl.</p>
<p>Apache Axis2/C to can be used to send and receive binaries as MTOM, SWA or base64 encoded. But ADB generated code still support to send and receive base64 encoded binaries only. So if you use contract first approach  with Axis2/C (i.e start with the WSDL, then write the service based on that), you have to use base64-encoded (non-optimized) as the binary transferring method. Note that you can use the other methods like MTOM or SWA, if you write the code to build and parse the xmls from AXIOM which is a general model for XML like DOM.</p>
<p>Say you have an element with base64Binary type in your request XML. So the schema for that element would be,</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:complexType</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"Person"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"image"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"xs:base64Binary"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
        ... <span style="color: #009900;"><span style="font-style: italic; color: #808080;">&lt;!-- some more elements --&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>After you code generated, you will get the adb_person.h and adb_person.c files with the following function prototypes and the implementations,</p>
<pre class="c">        <span style="font-style: italic; color: #808080;">/**
         * Constructor for creating adb_Person_t
         * @param env pointer to environment struct
         * @return newly created adb_Person_t object
         */</span>
        adb_Person_t* AXIS2_CALL
        adb_Person_create<span style="color: #66cc66;">(</span>
            <span style="color: #993333;">const</span> axutil_env_t *env <span style="color: #66cc66;">)</span>;

        <span style="font-style: italic; color: #808080;">/**
         * Free adb_Person_t object
         * @param  _Person adb_Person_t object to free
         * @param env pointer to environment struct
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
         */</span>
        axis2_status_t AXIS2_CALL
        adb_Person_free <span style="color: #66cc66;">(</span>
            adb_Person_t* _Person,
            <span style="color: #993333;">const</span> axutil_env_t *env<span style="color: #66cc66;">)</span>;

        <span style="font-style: italic; color: #808080;">/**
         * Getter for image.
         * @param  _Person adb_Person_t object
         * @param env pointer to environment struct
         * @return axutil_base64_binary_t*
         */</span>
        axutil_base64_binary_t* AXIS2_CALL
        adb_Person_get_image<span style="color: #66cc66;">(</span>
            adb_Person_t* _Person,
            <span style="color: #993333;">const</span> axutil_env_t *env<span style="color: #66cc66;">)</span>;

        <span style="font-style: italic; color: #808080;">/**
         * Setter for image.
         * @param  _Person adb_Person_t object
         * @param env pointer to environment struct
         * @param arg_image axutil_base64_binary_t*
         * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
         */</span>
        axis2_status_t AXIS2_CALL
        adb_Person_set_image<span style="color: #66cc66;">(</span>
            adb_Person_t* _Person,
            <span style="color: #993333;">const</span> axutil_env_t *env,
            axutil_base64_binary_t*  arg_image<span style="color: #66cc66;">)</span>;</pre>
<p>So you can manipulate the person element in c language using the create, get, set and free function.</p>
<pre class="c">    <span style="font-style: italic; color: #808080;">/* here the env is the axutil_env_t* instance - the axis2/c environment */</span>
    FILE *f = fopen<span style="color: #66cc66;">(</span><span style="color: #ff0000;">"./images/person.png"</span>, <span style="color: #ff0000;">"r+"</span><span style="color: #66cc66;">)</span>;
    <span style="color: #993333;">int</span> binary_count;
    <span style="font-style: italic; color: #808080;">/* binary read a function you may write to read the binary data to the
     variable binary and the count to the variable binary_count */</span>
    <span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> *binary = binary_read<span style="color: #66cc66;">(</span>f, env, &amp;binary_count<span style="color: #66cc66;">)</span>;
    axutil_base64_binary_t *base64 = axutil_base64_binary_create_with_plain_binary<span style="color: #66cc66;">(</span>
                                        env, binary, binary_count<span style="color: #66cc66;">)</span>;

    adb_Person_t *person = adb_Person_create<span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>;
    adb_Person_set_image<span style="color: #66cc66;">(</span>person, env, base64<span style="color: #66cc66;">)</span>;</pre>
<p>You can set this adb person directly to your request or to a setter of another adb instance to complete the ADB tree. So this way you can send binaries (as base64 encoded) using the Axis2/C ADB generated code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/11/24/sending-binary-with-apache-axis2c-adb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Axis2/C RESTful URL Mapping Algorithm</title>
		<link>http://www.dimuthu.org/blog/2008/11/21/apache-axis2c-restful-url-mapping-algorithm/</link>
		<comments>http://www.dimuthu.org/blog/2008/11/21/apache-axis2c-restful-url-mapping-algorithm/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 10:26:27 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[algorithm]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[RESTful]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[time complexity]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=664</guid>
		<description><![CDATA[Few weeks back I wrote a blog post about Writing RESTful Services in C which explain the use of Axis2/C REST API. Basically when you provide a HTTP Method (GET, POST, PUT or DELETE) and a HTTP URL, it is matched with a given HTTP method and a URL pattern in order to identify the [...]]]></description>
			<content:encoded><![CDATA[<p>Few weeks back I wrote a blog post about <a href="http://www.dimuthu.org/blog/2008/10/18/write-restful-services-in-c/">Writing RESTful Services in C</a> which explain the use of <a href="http://ws.apache.org/axis2/c">Axis2/C</a> REST API. Basically when you provide a HTTP Method (GET, POST, PUT or DELETE) and a HTTP URL, it is matched with a given HTTP method and a URL pattern in order to identify the operation and extract out the request parameters. For the example mentioned in the above <a href="http://www.dimuthu.org/blog/2008/10/18/write-restful-services-in-c/">blog</a>, we can summarize the URL mapping like this.</p>
<table border="1">
<tbody>
<tr style="background:#dddddd">
<td>Operation</td>
<td>HTTP Method</td>
<td>URL Pattern</td>
<td>Example Requests</td>
</tr>
<tr>
<td>getSubjects</td>
<td>GET</td>
<td>subjects</td>
<td>GET subjects</td>
</tr>
<tr>
<td>getSubjectInfoPerName</td>
<td>GET</td>
<td>subjects/{name}</td>
<td>GET subjects/maths</td>
</tr>
<tr>
<td>getStudnets</td>
<td>GET</td>
<td>students</td>
<td>GET students</td>
</tr>
<tr>
<td>getStudnetsInfoPerName</td>
<td>GET</td>
<td>students/{name}</td>
<td>GET students/john</td>
</tr>
<tr>
<td>getMarksPerSubjectPerStudent</td>
<td>GET</td>
<td>students/{student}/marks/{subject}</td>
<td>GET students/john/marks/maths</td>
</tr>
</tbody>
</table>
<p>You can watch <a href="http://labs.wso2.org/wsf/php/resource_view.php?url=RESTfulSchool">an application with this URL mapping in live</a>, written using <a href="http://wso2.org/projects/wsf/php">WSF/PHP</a> which in fact run Axis2/C algorithms underneath.</p>
<p>Last week I updated this REST mapping algorithm and started a <a href="http://www.nabble.com/REST-URL-Mapping---The-changes-done-in-pattern-matching-Algorithm-to20594898.html#a20594898">discussion about the changes on Axis2/C Dev list</a>. I thought it would be better explain the idea on by blog too.</p>
<p>What the early algorithm (before my changes) did was, it search each pattern in the order it was declared, and returns when a match is found. Sequential searching for a matching pattern can reduce the performance as the number of operations grows. So my solutions was to keep the url pattern in a multi level (recursive) structure and match the url from one level to another.</p>
<p>Here is the structure of the &#8216;c struct&#8217;. (defined in src/core/util/core_utils.c)</p>
<pre class="c"><span style="font-style: italic; color: #808080;">/* internal structure to keep the rest map in a multi level hash */</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> <span style="color: #66cc66;">{</span>
    <span style="font-style: italic; color: #808080;">/* the structure will keep as many as following fields */</span>

    <span style="font-style: italic; color: #808080;">/* if the mapped value is directly the operation */</span>
    axis2_op_t *op_desc;

    <span style="font-style: italic; color: #808080;">/* if the mapped value is a constant, this keeps a hash map of
    possible constants =&gt; corrosponding map_internal structure */</span>
    axutil_hash_t *consts_map;

    <span style="font-style: italic; color: #808080;">/* if the mapped value is a param, this keeps a hash map of
    possible param_values =&gt; corrosponding_map_internal structre */</span>
    axutil_hash_t *params_map;

<span style="color: #66cc66;">}</span> axutil_core_utils_map_internal_t;</pre>
<p>Here is how it will looks like when the above URL pattern set (shown in the above table) is kept inside this multi-level (recursive) structure.</p>
<pre>svc-&gt;op_rest_map  (hash)
                |
            "GET:students" --------- axutil_core_utils_map_internal_t (instance)
                |                                            |
                |                                        op_desc (axis2_op_t* for "GET students" op)
                |                                            |
                |                                        consts_map (empty hash)
                |                                            |
                |                                        params_map (hash)
                |                                                         |
                |                                                      "{student_id}" ------------- axutil_core_utils_map_internal_t (instance)
                |                                                                                            |
                |                                                                                op_desc (axis2_op_t* for "GET students/{student_id}" op)
                |                                                                                            |
                |                                                                                parms_map (empty hash)
                |                                                                                            |
                |                                                                                 const_map (hash)
                |                                                                                            |
                |                                                                                        "marks" ------------------- axutil_core_utils_map_internal_t (instance)
                |                                                                                                                            |
                |                                                                                                                    op_desc (NULL)
                |                                                                                                                            |
                |                                                                                                                   consts_map (empty hash)
                |                                                                                                                            |
                |                                                                                                                   params_map (hash)
                |                                                                                                                            |
                |                                                                                                                      "{subject_id}" ----------- axutil_core_utils_map_internal_t (instance)
                |                                                                                                                                                                               |
                |                                                                                                                                       op_desc (axis2_op_t* for "GET students/{student_id}/marks/{subject_id}" op)
                |                                                                                                                                                                               |
                |                                                                                                                                                                 consts_map / params_map (Both NULL)
                |
            "GET:students" --------- axutil_core_utils_map_internal_t (instance)
                                                            |
                                                        op_desc (axis2_op_t* for "GET students" op)
                                                            |
                                                        consts_map (empty hash)
                                                            |
                                                        params_map (hash)
                                                            |
                                                      "{student_id}" ------------- axutil_core_utils_map_internal_t (instance)
                                                                                                          |
                                                                                  op_desc (axis2_op_t* for "GET students/{student_id}" op)
                                                                                                          |
                                                                                             consts_map / params_map (Both NULL)</pre>
<p>This structure is build at the time the server initialize the services. (from the &#8220;axis2_svc_get_rest_op_list_with_method_and_location&#8221; function in src/core/description/svc.c)</p>
<p>As each request hit the service, the request HTTP method and the URL is matched (which we call &#8216;rest dispatching&#8217;) with the above structure using the following algorithm. (defined in the &#8220;axis2_rest_disp_find_op&#8221; function in src/core/engine/rest_disp.c). Note that here we are extracting out the user REST parameters as well, but it is not shown in here.</p>
<ol>
<li>The request URL is spitted in to URL components from &#8216;/&#8217; character. Retrive the instance of axutil_core_utils_map_internal_t  from the svc-&gt;rest_map to the varaible &#8216;mapping_struct&#8217;.</li>
<li>Check the existance of URL components, count(URL components) &gt; 0.</li>
<li>If it doesn&#8217;t exist any URL components, get the value of mapping_struct-&gt;op_desc where the mapping_struct is the current mapping instance of axutil_core_utils_map_internal_t. if the mapping_struct-&gt;op_desc is not NULL, we found the operation. If it is NULL just exit returning NULL.</li>
<li>Else If some URL component(s) exist, check the most former URL component in the mapping_struct-&gt;const_map hash. If mapping_struct-&gt;const_map['former_url_component'] is not NULL, assign the mapping struct-&gt;const_map['former_url_component'] value to mapping_struct and follow the step 2 with the remaining URL components. (note that here hash['key'] syntax is used to take the value for the key from the hash &#8216;hash&#8217;. If that returns TRUE, we found the opeartion, if not countine to step5.</li>
<li>if mapping_struct-&gt;const_map['former_url_component'] is NULL, match the former url component with each key (which is a URL component pattern) in mapping_struct-&gt;param_map hash. (We use the function <span> &#8220;axis2_core_utils_match_url_component_with_pattern&#8221; in src/core/util/core_utils.c to</span> map URL component with the URL component pattern<span>). If matching pattern found assign the mapping_struct-&gt;param_map['key'] to mapping struct and </span>follow the step 2 with the remaining URL components. If that returns TRUE for some key it will be the matching operation.</li>
</ol>
<p>Where as the earlier algorithm can be simplified to,</p>
<ol>
<li>Match the request URL with URL patterns of each operation. This will be like calling the function &#8220;<span>axis2_core_utils_match_url_component_with_pattern&#8221; (mentioned in step5 of the above algorithm) for the complete URL rather than for a URL component<br />
</span></li>
<li>If the pattern is matched, matching operation is the selected operation for the request.</li>
</ol>
<p>I approximately calculated the time complexity of both of these algorithm.</p>
<p>Here is the time complexity of the later described algorithm.</p>
<table border="1">
<tbody>
<tr>
<td>Average time complexity of iterating &#8216;n&#8217; number of operations</td>
<td>n/2 = O(n)</td>
</tr>
<tr>
<td>Time complexity of matching pattern with a URL with the length &#8216;p&#8217; (complexity of the &#8216;axis2_core_utils_match_url_component_with_pattern&#8217; function)</td>
<td>O(p^2)</td>
</tr>
<tr style="background:#eeeeee">
<td>Complete time complexity of the algorithm</td>
<td>O(n*p^2)</td>
</tr>
</tbody>
</table>
<p>Time complexity of the formerly described algorithm. (which is currently in the SVN).</p>
<table border="1">
<tbody>
<tr>
<td>Time Complexity of a Hash Search</td>
<td>O(1)</td>
</tr>
<tr>
<td>Average Number of has searches required. This is the average number of levels in the tree of recursive structures drawn above</td>
<td>long(n)/2 = O(log(n))</td>
</tr>
<tr>
<td>Time complexity of matching pattern with a URL component with the average length &#8216;d&#8217;, d &lt; p (p = the length of the complete URL)</td>
<td>O(d^2)</td>
</tr>
<tr>
<td>Number of time pattern matching is required = number of param components in the URL = k, k &lt; p/d (p = the length of the url, d = average length of the URL component)/</td>
<td>k = O(k)</td>
</tr>
<tr style="background:#eeeeee">
<td>Complete time complexity of the algorithm</td>
<td>O(log(n)*d^2*k)</td>
</tr>
</tbody>
</table>
<p>Considering the facts, O(logn) &lt; O(n),d &lt; p and k &lt; p/d we can safely conclude</p>
<p>O(long(n)*d^2*k) &lt; O(n*p^2)  =&gt; The newer algorithm has better (low) time complexity.</p>
<p>However the time complexity is valid only it takes high values for the parameters. For low values  the actual time taken by the newer algorithm can have high values, considering the constant overhead of the recursions and the hash search. So in order to judge the performance of the algorithm, we have to run some test cases and measure the actual times. Possibly a task for the weekend <img src='http://www.dimuthu.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/11/21/apache-axis2c-restful-url-mapping-algorithm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compiling and Debugging Axis2/C Services And Clients Using Visual Studio</title>
		<link>http://www.dimuthu.org/blog/2008/10/12/compiling-and-debugging-axis2c-services-and-clients-using-visual-studio/</link>
		<comments>http://www.dimuthu.org/blog/2008/10/12/compiling-and-debugging-axis2c-services-and-clients-using-visual-studio/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 15:05:02 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[compile]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[Headers]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[visual studio]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=462</guid>
		<description><![CDATA[I have been working in Linux for a long time and recently moved to windows for a little change. (Hopefully for a little time . I find it is really easy to create a project for an Axis2/C client or service with Visual Studio. (I&#8217;m using Visual Studio 2005). Anyway I thought it is better [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working in Linux for a long time and recently moved to windows for a little change. (Hopefully for a little time <img src='http://www.dimuthu.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . I find it is really easy to create a project for an Axis2/C client or service with Visual Studio. (I&#8217;m using Visual Studio 2005). Anyway I thought it is better to write down it somewhere so someone may find it useful.</p>
<p><strong>Compiling Axis2/C Client</strong></p>
<p>I&#8217;m using the math sample for this guide. You can find the source code inside &#8220;samples\client\math&#8221; directory of any  <a href="http://ws.apache.org/axis2/c/download.cgi">axis2/c binary or source</a>.</p>
<ol>
<li>Create a new Visual Studio C++ Project, Select the project type to &#8216;Win32 Console Application&#8217;. Give a name to the project (say &#8216;math_client&#8217;) and in the wizard choose &#8216;Empty Project&#8217;. Then you will have an empty C/C++ project.</li>
<li>Add the source files of the math samples to the project. You can do this by right clicking the project name in the Solution Explorer and clicking Add-&gt;Existing Item. After this step you will have axis2_math_stub.h in the Header Files section and the axis2_math_stub.c and math_client.c in the Source files section.</li>
<li>Add Axis2/C include file directory. For this, go to &#8216;Tools-&gt;Options&#8217; from the menu and select &#8216;Projects and Solutions-&gt;VC++ Directories&#8217; from the Tree menu. Select the &#8216;Include files&#8217; from &#8216;Show Directories for:&#8217; drop down menu and add the &#8216;Axis2/C installed dir/includes&#8217; directory. Note that if you follow this to add include directories you only need to do this only once for all the projects. If you want to do this only specifically to this project Go to &#8216;Project-&gt;Properties&#8217; from the menu and Go to &#8216;Configuration Properties-&gt;C/C++-&gt;General and add the directories under &#8216;Additional Include Directories&#8217;)</li>
<li>Add Axis2/C library directory. Here is how you do this. Go to the VC++ Directories form mentioned in the step 3 and select &#8216;Library files&#8217; from the &#8216;Show Directories for:&#8217; drop down menu. Then add the  &#8216;Axis2/C installed dir/lib&#8217; directory. If you add this here all the following project will use this directory to search for libraries. If you want this only to this project just skip this step and do what is specially mentioned in the step 5.</li>
<li>Declare what libraries to link. For this, go to &#8216;Project-&gt;Properties&#8217; from the menu and select &#8220;Configuration Properties-&gt;Linker-&gt;Input&#8217; from the tree menu. In the &#8216;Additional Dependencies&#8217; Text box add the following Axis2/C libraries.
<ul>
<li>axiom.lib</li>
<li>axutil.lib</li>
<li>axis2_engine.lib</li>
<li>axis2_parser.lib</li>
</ul>
<p>If you skipped the step 4, you have to type the complete path for the libraries.</li>
<li>So that&#8217;s all you have to do.  You can compile and run the client using F5 or Ctrl+F5.</li>
</ol>
<p><strong>Debugging Axis2/C Client</strong></p>
<ol>
<li>Since by default new project is created with the debug configurations, you can debug the program straight away. To test set a breakpoint at the start of the main function (in the math_client.c) and Run with Debugging (F5)</li>
</ol>
<p><strong>Compiling Axis2/C Service</strong></p>
<p>We will use the corrosponding math service to create a Visual Studio project. It is same as how you created the math client project. But it has very little differences. (It requires only one additional step)</p>
<ol>
<li>Create a project in Visual Studio. This time select &#8220;Win32 Project&#8221; as the project type. Give a name to the project (&#8220;math_service&#8221;) and continue to the wizard. In there select the &#8220;Application Type&#8221; to be &#8220;DLL&#8221; and tick the &#8220;Empty Project&#8221; so we will have an empty project to build a DLL.</li>
<li>Add the math service sample files to the project. You can find the source for the sample inside &#8220;samples\client\math&#8221; directory of the Axis2/c distribution.</li>
<li>Add the Axis2/C include directory. If you have done it earlier using &#8220;Tools-&gt;Options&#8221; dialog box you don&#8217;t need to do that again since that settings persist over every project. But if you did it using &#8220;Project-&gt;Properties&#8221; dialog box you have to redo the step3 described in compiling client section for this project too.</li>
<li>Add the Axis2/C library directory. Same as the step 4 in compiling client section.</li>
<li>Declare the libraries to link. Same as the step 5 in the comping client section.</li>
<li>Declare the &#8220;AXIS2_DECLARE_EXPORT&#8221; preprocessor constant. For this go to the &#8220;Project-&gt;Properties&#8221; and click the &#8220;Configuration Properties-&gt;C/C++-&gt;Preprocessor&#8221; and add the &#8220;AXIS2_DECLARE_EXPORT&#8221; at the end separated with a semi column.</li>
<li>That is all needed to compile the service. Now you can build the project using &#8220;Build-&gt;BuildSolution or just type F7.</li>
</ol>
<p><strong>Debugging Axis2/C Service</strong></p>
<ol>
<li>After you compile the source, you cand find the resulted DLL inside the debug directory of your project directory. Just copy it to the &lt;axis2 installed dir&gt;\services\math directory replacing math.dll file.</li>
<li>Then Run the simple Axis2 Http Server in the &lt;axis2 installed dir&gt;\bin.</li>
<li>Start the project you just created for the math service and go to &#8220;Debug-&gt;Attach To Process&#8221;. There you can see the list of running processes. Just select the axis2_http_server process.</li>
<li>Now as a test create a breakpoint at the start of axis2_math_add function in the math.c file. (You will get a warning that no symbol is loaded for the file, but you can ignore that for the moment)</li>
<li>Now send a request using the math client that you compiled earlier. You will see the breakpoint is hit in the service project. So you can debug the service as you like.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/10/12/compiling-and-debugging-axis2c-services-and-clients-using-visual-studio/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Invoking WSF/PHP Web Services Through Proxy</title>
		<link>http://www.dimuthu.org/blog/2008/10/06/invoking-wsfphp-web-services-through-proxy/</link>
		<comments>http://www.dimuthu.org/blog/2008/10/06/invoking-wsfphp-web-services-through-proxy/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 16:28:40 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[wsf/php]]></category>
		<category><![CDATA[wso2]]></category>
		<category><![CDATA[axis2.xml]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[proxyHost]]></category>
		<category><![CDATA[proxyPort]]></category>
		<category><![CDATA[WSClient]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=446</guid>
		<description><![CDATA[If you are behind a proxy server you need to configure your client to send the request through proxy. With WSF/PHP you can do it in two ways. 1. Setting proxy configuration in WSClient itself You can use the &#8216;proxyHost&#8217; and &#8216;proxyPort&#8217; options to provide the proxy information through WSClient. $client = new WSClient(array("to" =&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>If you are behind a proxy server you need to configure your client to send the request through proxy. With <a href="http://wso2.org/projects/wsf/php">WSF/PHP</a> you can do it in two ways.</p>
<p><strong>1. Setting proxy configuration in WSClient itself</strong></p>
<p>You can use the &#8216;proxyHost&#8217; and &#8216;proxyPort&#8217; options to provide the proxy information through <a href="http://wso2.org/project/wsf/php/2.0.0/docs/api_content.html#client">WSClient</a>.</p>
<pre class="php"><span style="color: #0000ff;">$client</span> = <span style="font-weight: bold; color: #000000;">new</span> WSClient<span style="color: #66cc66;">(</span><a href="http://www.php.net/array"><span style="color: #000066;">array</span></a><span style="color: #66cc66;">(</span><span style="color: #ff0000;">"to"</span> =&gt; <span style="color: #ff0000;">"http://my.external.host/service_url"</span>,
                  <span style="color: #ff0000;">"proxyHost"</span> =&gt; PROXY_HOST,
                  <span style="color: #ff0000;">"proxyPort"</span> =&gt; PROXY_PORT<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;</pre>
<p><strong>2. Use the axis2.xml</strong></p>
<p>Change the <a href="http://ws.apache.org/axis2/c/docs/axis2c_manual.html#appA">axis2.xml</a> to the following. (axis2.xml is in the wsf_c directory which is by default installed inside the php extension directory unless you specified it explicitly in your php.ini &#8216;wsf.home&#8217; entry)</p>
<pre class="xml">    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;transportSender</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"http"</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"axis2_http_sender"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
        <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"PROTOCOL"</span> <span style="color: #000066;">locked</span>=<span style="color: #ff0000;">"false"</span><span style="font-weight: bold; color: black;">&gt;</span></span>HTTP/1.1<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"xml-declaration"</span> <span style="color: #000066;">insert</span>=<span style="color: #ff0000;">"false"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
      <span style="color: #009900;"><span style="font-style: italic; color: #808080;">&lt;!--Here is where you set the proxy host and the port--&gt;</span></span>
      <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"PROXY"</span> <span style="color: #000066;">proxy_host</span>=<span style="color: #ff0000;">"MY_PROXY_HOST"</span> <span style="color: #000066;">proxy_port</span>=<span style="color: #ff0000;">"MY_PROXY_IP"</span> <span style="color: #000066;">locked</span>=<span style="color: #ff0000;">"true"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/transportSender<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>So if you want only to use the proxy for particular clients, you can use the former approach. But if you want to use the proxy for all the clients in your system just use the later approach so you don&#8217;t need to edit each client.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/10/06/invoking-wsfphp-web-services-through-proxy/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Understanding Apache Axis2/C Services</title>
		<link>http://www.dimuthu.org/blog/2008/10/02/understanding-apache-axis2c-services/</link>
		<comments>http://www.dimuthu.org/blog/2008/10/02/understanding-apache-axis2c-services/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 10:20:36 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[axis2.xml]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[Skeleton]]></category>
		<category><![CDATA[svc_skeleton]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=425</guid>
		<description><![CDATA[If you have ever written an Apache Axis2/C service, there is a 99.9% chance that you have used the codegen tool to generate the code for the service. If so you only need to write your business logic inside functions generated by the the tool. But there may be situations that you can&#8217;t use the [...]]]></description>
			<content:encoded><![CDATA[<p>If you have ever written an <a href="http://ws.apache.org/axis2/c">Apache Axis2/C</a> service, there is a 99.9% chance that you have used the codegen tool to generate the code for the service. If so you only need to write your business logic inside functions generated by the the tool.</p>
<p>But there may be situations that you can&#8217;t use the codegen tool to get your work done. May be you don&#8217;t have a WSDL. Or codegen tool fails generating code for you WSDL (very few chance <img src='http://www.dimuthu.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>In these situations you have to go to writing the complete service manually, I.e. You will write the code for the business logic + Axis2 Skeleton (code to plug the service logic to axis2/c).</p>
<p>Axis2/C service consists on:</p>
<ul>
<li>service.xml &#8211; Simple way to describe the service and operation. (Far simpler than a wsdl)</li>
<li>Skeleton &#8211; c pseudo class inherited from axis2_svc_skeleton</li>
<li>Service logic &#8211; You service logic per service operation</li>
</ul>
<p><strong>services.xml</strong></p>
<p>This contain the name and some description of the service, the name of the .dll (in windows) or .so (in linux) to load the service and list of operations with their parameters.</p>
<p>E.g.</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;service</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"echo"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
  <span style="color: #009900;"><span style="font-style: italic; color: #808080;">&lt;!-- dll or so name of the service --&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"ServiceClass"</span> <span style="color: #000066;">locked</span>=<span style="color: #ff0000;">"xsd:false"</span><span style="font-weight: bold; color: black;">&gt;</span></span>echo<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;description<span style="font-weight: bold; color: black;">&gt;</span></span></span>This is a testing service, to test whether the system is working or not<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/description<span style="font-weight: bold; color: black;">&gt;</span></span></span> 

  <span style="color: #009900;"><span style="font-style: italic; color: #808080;">&lt;!-- list of operations --&gt;</span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;operation</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"echoString"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
    <span style="color: #009900;"><span style="font-style: italic; color: #808080;">&lt;!-- addressing information for the operation--&gt;</span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;parameter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"wsamapping"</span><span style="font-weight: bold; color: black;">&gt;</span></span>http://ws.dimuthu.org/axis2/echoString<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/parameter<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/operation<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/service<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>In addition to shown ones, there are a bunch of parameters available to customize your service. Visit <a href="http://ws.apache.org/axis2/c/docs/axis2c_manual.html#appB">Axis2/C manual</a> for more.<br />
<strong>Skeleton</strong><br />
This is the code that form the dll for your service. At least you should implement the following set of functions there.</p>
<ul>
<li>Required function to create any axis2/c DLL
<ul>
<li>axis2_get_instance &#8211; Call at the creation of the DLL</li>
<li>axis2_remove_instance &#8211; Call at the removal of the DLL</li>
</ul>
</li>
<li>Functions to be implement the axis2_svc_skeleton interface (sorry I&#8217;m using the java jargons)
<ul>
<li>init- Initialize the service (execute per start of the server)</li>
<li>invoke &#8211; invocation of the service (execute per each client request)</li>
<li>on_fault &#8211; invocation of the fault (execute if invoke returns NULL with error set)</li>
<li>free &#8211; Freeing the service (execute per stop of the server)</li>
</ul>
</li>
<li> In addition to these mandatory functions I will be using axis2_echo_create to create the service skeleton for the echo service.</li>
</ul>
<p>I will start with showing the structure of the service skeleton functions first.</p>
<pre class="c"><span style="font-style: italic; color: #808080;">/**
 * echo free method
 */</span>
<span style="color: #993333;">int</span> AXIS2_CALL echo_free<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t * svc_skeleton,
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>;

<span style="font-style: italic; color: #808080;">/**
 * echo invoke method
 */</span>
axiom_node_t *AXIS2_CALL echo_invoke<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t * svc_skeleton,
    <span style="color: #993333;">const</span> axutil_env_t * env,
    axiom_node_t * node,
    axis2_msg_ctx_t * msg_ctx<span style="color: #66cc66;">)</span>;

<span style="font-style: italic; color: #808080;">/**
 * echo init method
 */</span>
<span style="color: #993333;">int</span> AXIS2_CALL echo_init<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t * svc_skeleton,
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>;

<span style="font-style: italic; color: #808080;">/**
 * echo on_fault method
 */</span>
axiom_node_t *AXIS2_CALL echo_on_fault<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t * svc_skeli,
    <span style="color: #993333;">const</span> axutil_env_t * env,
    axiom_node_t * node<span style="color: #66cc66;">)</span>;</pre>
<p>Note that you have the freedom to give any name to each of these function. In fact you should give a name with your service name as the prefix to avoid name conflicts. Then you can specify service skeleton to take these functions to represent to init, invoke, on_fault, free methods using the following code.</p>
<pre class="c"><span style="font-style: italic; color: #808080;">/**
 * you should specify your functions set exactly in the order
 * init, invoke, on_fault, free
 */</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">const</span> axis2_svc_skeleton_ops_t echo_svc_skeleton_ops_var = <span style="color: #66cc66;">{</span>
    echo_init,
    echo_invoke,
    echo_on_fault,
    echo_free
<span style="color: #66cc66;">}</span>;

<span style="font-style: italic; color: #808080;">/**
 * Create function
 */</span>
axis2_svc_skeleton_t *
axis2_echo_create<span style="color: #66cc66;">(</span>
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
    axis2_svc_skeleton_t *svc_skeleton = <span style="font-weight: bold; color: #000000;">NULL</span>;
    <span style="font-style: italic; color: #808080;">/* Allocate memory for the structs */</span>
    svc_skeleton = AXIS2_MALLOC<span style="color: #66cc66;">(</span>env-&gt;allocator, <span style="color: #993333;">sizeof</span><span style="color: #66cc66;">(</span>axis2_svc_skeleton_t<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>;

    <span style="font-style: italic; color: #808080;">/* you give the function pointers array to the ops of the skeleton */</span>
    svc_skeleton-&gt;ops = &amp;echo_svc_skeleton_ops_var;

    svc_skeleton-&gt;func_array = <span style="font-weight: bold; color: #000000;">NULL</span>;

    <span style="color: #b1b100;">return</span> svc_skeleton;
<span style="color: #66cc66;">}</span></pre>
<p>So you create the service skeleton for your echo service inside the axis2_echo_create function. In fact you need to call this function from the DLL creation function (i.e. &#8216;axis2_get_instance&#8217; funciton). And in the &#8216;axis2_remove_instance&#8217; function you call the macro AXIS2_SVC_SKELETON_FREE which in fact call the echo_free function to free the resource at the removal of DLL. Here are the implementation for the DLL creation and removal functions in this particular service.</p>
<pre class="c"><span style="font-style: italic; color: #808080;">/**
 * Calls at the creation of the dll.
 */</span>
AXIS2_EXPORT <span style="color: #993333;">int</span>
axis2_get_instance<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t ** inst,
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
    *inst = axis2_echo_create<span style="color: #66cc66;">(</span>env<span style="color: #66cc66;">)</span>;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!<span style="color: #66cc66;">(</span>*inst<span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        <span style="color: #b1b100;">return</span> AXIS2_FAILURE;
    <span style="color: #66cc66;">}</span>

    <span style="color: #b1b100;">return</span> AXIS2_SUCCESS;
<span style="color: #66cc66;">}</span>

<span style="font-style: italic; color: #808080;">/**
 * Calls at the removal of the dll.
 */</span>
AXIS2_EXPORT <span style="color: #993333;">int</span>
axis2_remove_instance<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t * inst,
    <span style="color: #993333;">const</span> axutil_env_t * env<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
    axis2_status_t status = AXIS2_FAILURE;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>inst<span style="color: #66cc66;">)</span>
    <span style="color: #66cc66;">{</span>
        status = AXIS2_SVC_SKELETON_FREE<span style="color: #66cc66;">(</span>inst, env<span style="color: #66cc66;">)</span>;
    <span style="color: #66cc66;">}</span>
    <span style="color: #b1b100;">return</span> status;
<span style="color: #66cc66;">}</span></pre>
<p>Up to this, it was all about preparing the service skeleton, So where you put your business logic?.</p>
<p><strong>Service logic</strong></p>
<p>Just create a function with the following format.</p>
<pre class="c">axiom_node_t *axis2_echo_echo<span style="color: #66cc66;">(</span>
    <span style="color: #993333;">const</span> axutil_env_t * env,
    axiom_node_t * input_node<span style="color: #66cc66;">)</span> <span style="color: #66cc66;">{</span>

    <span style="font-style: italic; color: #808080;">/* Write your business logic Right Here */</span>
<span style="color: #66cc66;">}</span></pre>
<p>Here you extract out the input parameters from the the input_node and build the return node based on your output parameters. (Note that even though this is an echo example you can&#8217;t return the same input node as the output node, instead you have to replicate the input node and return it to avoid the double freeing)<br />
Since this particular example you only have one operation you can call your business logic right inside of your echo_invoke function. But it doens&#8217;t work for cases where multiple operations present. Here is the right way to do it.</p>
<pre class="c"><span style="font-style: italic; color: #808080;">/*
 * This method invokes the right service logic
 */</span>
axiom_node_t *AXIS2_CALL
echo_invoke<span style="color: #66cc66;">(</span>
    axis2_svc_skeleton_t * svc_skeleton,
    <span style="color: #993333;">const</span> axutil_env_t * env,
    axiom_node_t * node,
    axis2_msg_ctx_t * msg_ctx<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
	axis2_op_ctx_t *operation_ctx = <span style="font-weight: bold; color: #000000;">NULL</span>;
	axis2_op_t *operation = <span style="font-weight: bold; color: #000000;">NULL</span>;
	axutil_qname_t *op_qname = <span style="font-weight: bold; color: #000000;">NULL</span>;
	axis2_char_t *op_name = <span style="font-weight: bold; color: #000000;">NULL</span>;

	<span style="font-style: italic; color: #808080;">/* logic to get the op name from message context */</span>
	operation_ctx = axis2_msg_ctx_get_op_ctx<span style="color: #66cc66;">(</span>msg_ctx, env<span style="color: #66cc66;">)</span>;
	operation = axis2_op_ctx_get_op<span style="color: #66cc66;">(</span>operation_ctx, env<span style="color: #66cc66;">)</span>;
	op_qname = <span style="color: #66cc66;">(</span>axutil_qname_t *<span style="color: #66cc66;">)</span>axis2_op_get_qname<span style="color: #66cc66;">(</span>operation, env<span style="color: #66cc66;">)</span>;
	op_name = axutil_qname_get_localpart<span style="color: #66cc66;">(</span>op_qname, env<span style="color: #66cc66;">)</span>;

	<span style="font-style: italic; color: #808080;">/* compare it with our operation name, this is useful when
	   there are multiple operations exist */</span>
	<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>op_name<span style="color: #66cc66;">)</span>
	<span style="color: #66cc66;">{</span>
		<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">(</span>!axutil_strcmp<span style="color: #66cc66;">(</span>op_name, <span style="color: #ff0000;">"echoString"</span><span style="color: #66cc66;">)</span><span style="color: #66cc66;">)</span>
		<span style="color: #66cc66;">{</span>
			<span style="color: #b1b100;">return</span> axis2_echo_echo<span style="color: #66cc66;">(</span>env, node<span style="color: #66cc66;">)</span>;
		<span style="color: #66cc66;">}</span>
	<span style="color: #66cc66;">}</span>

	<span style="font-style: italic; color: #808080;">/* set error in the failure path */</span>
	AXIS2_ERROR_SET<span style="color: #66cc66;">(</span>env-&gt;error, AXIS2_ERROR_OP_NAME_MISSING, AXIS2_FAILURE<span style="color: #66cc66;">)</span>;

	<span style="font-style: italic; color: #808080;">/* log the error */</span>
	AXIS2_LOG_ERROR<span style="color: #66cc66;">(</span> env-&gt;log, AXIS2_LOG_SI, <span style="color: #ff0000;">"op name %s is not known"</span>, op_name<span style="color: #66cc66;">)</span>;

	<span style="color: #b1b100;">return</span> <span style="font-weight: bold; color: #000000;">NULL</span>;
<span style="color: #66cc66;">}</span></pre>
<p>So that&#8217;s the part you write the code. Compile the code linking necessary libraries in the lib directory of your axis2/c pack and don&#8217;t forget to include the necessary axis2/c headers.</p>
<ul>
<li> Necessary libraries for linux (Note: Some libraries are not directly called from your code, but it s better link all as some systems may complain about missing symbols in run time)
<ul>
<li> libaxutil.so</li>
<li> libaxis2_axiom.so</li>
<li> libaxis2_engine.so</li>
<li> libaxis2_parser.so</li>
<li> libpthread.so</li>
<li> libaxis2_http_sender.so</li>
<li> libaxis2_http_receiver.so</li>
<li> libguththila.so</li>
</ul>
</li>
<li> Necessary libraries for Windows
<ul>
<li> axiom.lib</li>
<li> axis2_engine.lib</li>
<li> axis2_parser.lib</li>
<li> axutil.lib</li>
</ul>
</li>
<li> Necessary header files (for both windows and linux)
<ul>
<li> axis2_svc_skeleton.h &#8211; To create instance of svc_skeleton</li>
<li> axis2_msg_ctx.h &#8211; Required in retrieving the dispatched operation name</li>
</ul>
</li>
</ul>
<p>If you follow this post up to now, this is the time you deploy the service with Axis2/C. Create a directory called &#8216;echo&#8217; inside the services directory of axis2 repository (the root directory of you put axis2/c binary) and copy the services.xml and the dll  in to that. (The DLL should be in the name echo.dll or libecho.so, if you change the dll name you should update the services.xml &#8220;ServiceClass&#8221; parameter).</p>
<p>Start the axis2 simple server (which is located in the &lt;axis2_c_repo&gt;/bin) and you are done. Your service will be deployed in &#8220;http://localhost/axis2/services/echo&#8221;. Use this endpoint to access your brand new service.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/10/02/understanding-apache-axis2c-services/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Use Axis2/C WSDL2C With Unwrapped Mode for Simpler Code</title>
		<link>http://www.dimuthu.org/blog/2008/09/15/use-axis2c-wsdl2c-with-unwrapped-mode-for-simpler-code/</link>
		<comments>http://www.dimuthu.org/blog/2008/09/15/use-axis2c-wsdl2c-with-unwrapped-mode-for-simpler-code/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 15:10:37 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[adb]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[codegen]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[WSDL]]></category>
		<category><![CDATA[wsdl2c]]></category>
		<category><![CDATA[xml schema]]></category>
		<category><![CDATA[Code generation]]></category>
		<category><![CDATA[Easier]]></category>
		<category><![CDATA[Simple]]></category>
		<category><![CDATA[unwrapped]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=263</guid>
		<description><![CDATA[WSDL2Java and WSDL2C tools shipped with the Axis2/Java project are used to generate Stubs(client side) and Skeletons(Server Side) respectively for Axis2/Java and Axis2/C codes. This make the development of web services and consumers more quicker and easier. The tools come with many options allowing the user to customize the code generation. One of the such [...]]]></description>
			<content:encoded><![CDATA[<p>WSDL2Java and WSDL2C tools shipped with the <a href="http://ws.apache.org/axis2">Axis2/Java project</a> are used to generate Stubs(client side) and Skeletons(Server Side) respectively for Axis2/Java and Axis2/C codes. This make the development of web services and consumers more quicker and easier.</p>
<p>The tools come with many options allowing the user to customize the code generation. One of the such option is &#8216;-uw&#8217; which used to turn on the &#8216;unwrapping&#8217; mode. WSDL2Java project had this option for a long time, But it is just Today I was able to enable that option in the WSDL2C tool. So lets see how it make the code easier.</p>
<p>Say you have the &#8216;simpleAdd&#8217; operation with the following schema,</p>
<pre>            <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"simpleAdd"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
                <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:element</span> <span style="color: #000066;">minOccurs</span>=<span style="color: #ff0000;">"0"</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"param0"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"xs:int"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
                        <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:element</span> <span style="color: #000066;">minOccurs</span>=<span style="color: #ff0000;">"0"</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"param1"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"xs:int"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:element</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"simpleAddResponse"</span><span style="font-weight: bold; color: black;">&gt;</span></span>
                <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
                    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
                        <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;xs:element</span> <span style="color: #000066;">minOccurs</span>=<span style="color: #ff0000;">"0"</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"return"</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">"xs:int"</span><span style="font-weight: bold; color: black;">/&gt;</span></span>
                    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:sequence<span style="font-weight: bold; color: black;">&gt;</span></span></span>
                <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:complexType<span style="font-weight: bold; color: black;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/xs:element<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>When you generate the code for server side with Java using the following command, (note the option -uw which stands for &#8216;unwrapping&#8217;)</p>
<pre>wsdl2java.sh -uri xxx.wsdl -u -ss -sd -uw</pre>
<p>it gives you the following service function.</p>
<pre><span style="font-weight: bold; color: #000000;">public</span> <span style="color: #993333;">int</span> simpleAdd<span style="color: #66cc66;">(</span><span style="color: #993333;">int</span> param0, <span style="color: #993333;">int</span> param1<span style="color: #66cc66;">)</span>
<span style="color: #66cc66;">{</span>
    <span style="font-style: italic; color: #808080;">//TODO : fill this with the necessary business logic</span>
<span style="color: #66cc66;">}</span></pre>
<p>Note the input and output parameters of the function are simple types. If you don&#8217;t give the &#8216;-uw&#8217; option, You will instead get a function with input and output variables as class names wrapping these simple types which is not this much straight forward.</p>
<p>So now the same is available with C. You can use  WSDl2C tool with the same option set to generate a very simple service API.</p>
<pre>wsdl2c.sh -uri xxx.wsdl -u -ss -sd -uw</pre>
<p>And here is the service logic you may write, Can you think of an API simpler than this,</p>
<pre>        <span style="font-style: italic; color: #808080;">/**
         * auto generated function definition signature
         * for "simpleAdd|http://ws.apache.org/axis2" operation.
         * @param env environment ( mandatory)
         * @param _param0 of the int
         * @param _param1 of the int
         *
         * @return int
         */</span>
        <span style="color: #993333;">int</span> axis2_skel_UnwrappedAdder_simpleAdd<span style="color: #66cc66;">(</span><span style="color: #993333;">const</span> axutil_env_t *env,
                                              <span style="color: #993333;">int</span> _param0,
                                              <span style="color: #993333;">int</span> _param1 <span style="color: #66cc66;">)</span>

        <span style="color: #66cc66;">{</span>
          <span style="color: #b1b100;">return</span> _param0 + _param1;
        <span style="color: #66cc66;">}</span></pre>
<p>You can find the code for complete case (wsdl, skel and stub) in the <a href="https://issues.apache.org/jira/secure/attachment/12390112/unwrapped.zip"> Axis2/C Jira Attachment space for the &#8216;unwrapping&#8217; issue</a>. Note that this update is only available in the nightly build and not in the release. You can download the nightly build from <a href="http://builder.wso2.org/browse/AXIS2-NIGHTLY">wso2&#8242;s axis2/java nightly build page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/09/15/use-axis2c-wsdl2c-with-unwrapped-mode-for-simpler-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to Hack Axis2 Codegen templates from an Axis2 Binary</title>
		<link>http://www.dimuthu.org/blog/2008/09/13/how-to-hack-axis2-codegen-templates-from-a-axis2-binary/</link>
		<comments>http://www.dimuthu.org/blog/2008/09/13/how-to-hack-axis2-codegen-templates-from-a-axis2-binary/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 14:35:17 +0000</pubDate>
		<dc:creator>dimuthu</dc:creator>
				<category><![CDATA[adb]]></category>
		<category><![CDATA[axis2/c]]></category>
		<category><![CDATA[codegen]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[Tutorial/Guide]]></category>
		<category><![CDATA[web services]]></category>
		<category><![CDATA[WSDL]]></category>
		<category><![CDATA[wsdl2c]]></category>
		<category><![CDATA[xml schema]]></category>
		<category><![CDATA[Axis2/Java]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[Custom templates]]></category>
		<category><![CDATA[Skeleton]]></category>
		<category><![CDATA[Stub]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://www.dimuthu.org/?p=255</guid>
		<description><![CDATA[I have been working for Axis2/C codegen tool for sometime now and I found lot of users who want to edit the codegen templates for a more optimized code specific to their use cases. This is mainly because codegen tool generates a very general code (For an example lot of unused variables generated for some [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working for <a href="http://ws.apache.org/axis2/c/">Axis2/C</a> codegen tool for sometime now and I found lot of users who want to edit the codegen templates for a more optimized code specific to their use cases. This is mainly because codegen tool generates a very general code (For an example lot of unused variables generated for some WSDLs, but they are used in some other WSDLs) where as mostly &#8216;C&#8217; people prefer to be as optimized as possible. Axis2 Java templates are more stable and not needed to customized as much as C templates, but Java developers too may find it is really useful to edit them in a case they need some customizations.</p>
<p>Both Axis2 C and Java tools comes with <a href="http://ws.apache.org/axis2/">Axis2/Java project</a>. So you may already have downloaded the latest <a href="http://ws.apache.org/axis2/download.cgi">Axis2/Java release</a> or <a href="http://builder.wso2.org/browse/AXIS2-NIGHTLY">the Axis2/Java nightly build</a>. As per title you can do this customization not only in the source but also in the binary pack. So I assume you have the binary pack.</p>
<p>Codegen tool mainly comes within two jars inside the lib directory of your Axis2/Java pack. (Here xxxx should be replaced with the particular jar version, it can be 1.4, 1.4.1 or SNAPSHOT)</p>
<ul>
<li>axis2-codegen-xxxx.jar &#8211; The core classes of the codegen (This is where WSDL2C and WSDL2Java classes reside)</li>
<li>axis2-adb-codegen-xxxx.jar &#8211; This is the library containing the adb component of the codegen tool. ADB (Axis2 Data Binding) is the native databinding format of Axis2 which convert your xml schema to a more programmer friendly set of java classes or &#8216;C&#8217; structures. The XSD2Java class comes in this jar.</li>
</ul>
<p><strong>Editing the Stub and Skeleton templates</strong></p>
<p>When you unpack the axis2-codegen-xxxx.jar</p>
<pre>jar xf axis2-codegen-xxxx.jar</pre>
<p>you can find the template for Stub and Skel in org/apache/axis2/wsdl/template/c or org/apache/axis2/wsdl/template/java directories.</p>
<ul>
<li>Stub For C &#8211; org/apache/axis2/wsdl/template/c/StubSourceTemplate.xsl (source) and org/apache/axis2/wsdl/template/c/StubHeaderTemplate.xsl (header)</li>
<li>Skeleton for C &#8211; org/apache/axis2/wsdl/template/c/SkelSourceTemplate.xsl (source) and org/apache/axis2/wsdl/template/c/SkelHeaderTemplate.xsl (header)</li>
<li>Stub For Java &#8211; org/apache/axis2/wsdl/template/java/InterfaceImplementationTemplate.xsl</li>
<li>Skel For Java &#8211; org/apache/axis2/wsdl/template/java/MessageReceiverTemplate.xsl (Message Reciever) and org/apache/axis2/wsdl/template/java/SkeletonTemplate.xsl (skeleton)</li>
</ul>
<p>These templates are written is XSL. Even if you are an XSL expert, you may find little difficult to understand whole lot of codes in there. But if you really know what you need to change, you can track back the lines (may be using comment or some specific static set of code). So you don&#8217;t actually need to know any XSL to do these little customizations.</p>
<p>After you do the change simply pack the classes (which are in the &#8216;org&#8217; directory) as the jar with the same name.</p>
<pre>jar cf axis2-codegen-xxxx.jar org</pre>
<p><strong>Editing the ADB templates</strong></p>
<p>You can similarly observe the axis2-adb-codegen-xxxx.jar. All the templates are in the org/apache/axis2/schema/template/ directory.</p>
<ul>
<li>C ADB templates &#8211; org/apache/axis2/schema/template/CADBBeanTemplateHeader.xsl (Source) and org/apache/axis2/schema/template/CADBBeanTemplateHeader.xsl (Header)</li>
<li>Java ADB template &#8211; org/apache/axis2/schema/template/ADBBeanTemplate.xsl</li>
</ul>
<p>You will find the template for the Java classes and C structures there. In C code generation if you find some variables are not used throughout your WSDLs, you can remove directly if from the templates. And some constants which are defined to allocate memory can be changed to suit to your application.</p>
<p>Anyway after all these notes, I have to say it is not really recommended to hack a code specific to your application. If you found a change general to all the applications you better submit the patch to the Axis2 community, so others too can use it. Otherwise whenever you do a upgrade you have to do this again on your own. But I hope these tips may be useful specially when you are working with ADB to do your own experiments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dimuthu.org/blog/2008/09/13/how-to-hack-axis2-codegen-templates-from-a-axis2-binary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

