You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by da...@apache.org on 2006/04/07 10:35:42 UTC
svn commit: r392213 - in /webservices/axis2/trunk/c:
samples/client/echo_non_blocking/echo_client.c xdocs/docs/userguide2.html
Author: damitha
Date: Fri Apr 7 01:35:38 2006
New Revision: 392213
URL: http://svn.apache.org/viewcvs?rev=392213&view=rev
Log:
Updated echo nonblocking sample and added documentation
Modified:
webservices/axis2/trunk/c/samples/client/echo_non_blocking/echo_client.c
webservices/axis2/trunk/c/xdocs/docs/userguide2.html
Modified: webservices/axis2/trunk/c/samples/client/echo_non_blocking/echo_client.c
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/samples/client/echo_non_blocking/echo_client.c?rev=392213&r1=392212&r2=392213&view=diff
==============================================================================
--- webservices/axis2/trunk/c/samples/client/echo_non_blocking/echo_client.c (original)
+++ webservices/axis2/trunk/c/samples/client/echo_non_blocking/echo_client.c Fri Apr 7 01:35:38 2006
@@ -37,10 +37,25 @@
#include <axis2_soap_fault_code.h>
#include <axis2_soap_fault_role.h>
#include <platforms/axis2_platform_auto_sense.h>
+#include <axis2_async_result.h>
+
+/* my on_complete callback function */
+axis2_status_t
+my_on_complete(struct axis2_callback *callback,
+ axis2_env_t **env);
+
+/* my on_error callback function */
+axis2_status_t
+my_on_error(struct axis2_callback *callback,
+ axis2_env_t **env,
+ int exception);
axis2_om_node_t *
build_om_programatically(axis2_env_t **env);
+/* to check whether the callback is completed */
+int isComplete = 0;
+
int main(int argc, char** argv)
{
axis2_om_node_t *node = NULL;
@@ -53,7 +68,6 @@
axis2_char_t *address = NULL;
axis2_char_t *wsa_action = NULL;
axis2_char_t *client_home = NULL;
- axis2_om_node_t *ret_node = NULL;
axis2_svc_t *svc = NULL;
axis2_op_t *op = NULL;
axis2_call_t *call = NULL;
@@ -63,8 +77,6 @@
axis2_endpoint_ref_t* endpoint_ref = NULL;
axis2_conf_t *conf = NULL;
axis2_callback_t* callback = NULL;
- int count = 0;
- axis2_soap_envelope_t *soap_envelope = NULL;
allocator = axis2_allocator_init (NULL);
error = axis2_error_create(allocator);
@@ -140,58 +152,43 @@
printf("ERROR: operation not present in service\n");
return -1;
}
+
+ /* create the callback object with default
+ on_complete and on_error callback functions*/
callback = axis2_callback_create(&env);
-
+
+ /* set our on_complete fucntion pointer to the callback object */
+ AXIS2_CALLBACK_SET_ON_COMPLETE(callback, my_on_complete);
+
+ /* set our on_error function pointer to the callback object */
+ AXIS2_CALLBACK_SET_ON_ERROR(callback, my_on_error);
+
+ /* invoke the operation and get the control back to the main
+ program immediately (without blocking)*/
AXIS2_CALL_INVOKE_NON_BLOCKING(call, &env, op, msg_ctx, callback);
- printf("Non blocking call invoked\n");
+ printf("Non blocking call invoked - Control back to Main Program\n");
+
+ /** this is simply to keep the parent thread running
+ until our on_complete or on_error is invoked
+ */
+ while(1)
+ {
+ if (isComplete)
+ {
+ /* we are done with the callback */
+ break;
+ }
+ }
- printf("\n");
- while (!AXIS2_CALLBACK_GET_COMPLETE(callback, &env))
- {
- if (count++ > 100)
- break;
- AXIS2_USLEEP(200);
- }
-
- do
- {
- soap_envelope = AXIS2_CALLBACK_GET_ENVELOPE(callback, &env);
- AXIS2_USLEEP(200);
- count++;
- } while (!soap_envelope && count < 200);
-
- if (soap_envelope)
- ret_node = AXIS2_SOAP_ENVELOPE_GET_BASE_NODE(soap_envelope, &env);
-
- if(ret_node)
- {
- axis2_xml_writer_t *writer = NULL;
- axis2_om_output_t *om_output = NULL;
- axis2_char_t *buffer = NULL;
-
- printf("\necho stub invoke SUCCESSFUL!\n");
- writer = axis2_xml_writer_create_for_memory(&env, NULL, AXIS2_TRUE, 0);
- om_output = axis2_om_output_create (&env, writer);
-
- AXIS2_OM_NODE_SERIALIZE (ret_node, &env, om_output);
- buffer = AXIS2_XML_WRITER_GET_XML(writer, &env);
- printf ("\nReceived OM node in XML : %s\n", buffer);
- AXIS2_OM_OUTPUT_FREE(om_output, &env);
- AXIS2_FREE(env->allocator, buffer);
- }
- else
- {
- AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"
- " %d :: %s", env->error->error_number,
- AXIS2_ERROR_GET_MESSAGE(env->error));
- printf("echo stub invoke FAILED!\n");
- }
-
if (call)
{
AXIS2_CALL_FREE(call, &env);
}
+ if (callback)
+ {
+ AXIS2_CALLBACK_FREE(callback, &env);
+ }
return status;
}
@@ -227,5 +224,71 @@
AXIS2_FREE((*env)->allocator, buffer);
return echo_om_node;
+}
+
+axis2_status_t
+my_on_complete(struct axis2_callback *callback,
+ axis2_env_t **env)
+{
+ /** SOAP response has arrived here; get the soap envelope
+ from the callback object and do whatever you want to do with it */
+
+ axis2_soap_envelope_t *soap_envelope = NULL;
+ axis2_om_node_t *ret_node = NULL;
+
+ axis2_xml_writer_t *writer = NULL;
+ axis2_om_output_t *om_output = NULL;
+ axis2_char_t *buffer = NULL;
+
+ printf("inside on_complete_callback function\n");
+
+ soap_envelope = AXIS2_CALLBACK_GET_ENVELOPE(callback, env);
+
+ if (!soap_envelope)
+ {
+ AXIS2_LOG_ERROR((*env)->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"
+ " %d :: %s", (*env)->error->error_number,
+ AXIS2_ERROR_GET_MESSAGE((*env)->error));
+ printf("echo stub invoke FAILED!\n");
+ return AXIS2_FAILURE;
+ }
+
+ ret_node = AXIS2_SOAP_ENVELOPE_GET_BASE_NODE(soap_envelope, env);
+
+ if(!ret_node)
+ {
+ AXIS2_LOG_ERROR((*env)->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"
+ " %d :: %s", (*env)->error->error_number,
+ AXIS2_ERROR_GET_MESSAGE((*env)->error));
+ printf("echo stub invoke FAILED!\n");
+ return AXIS2_FAILURE;
+ }
+
+ /*we just serialize the SOAP message and output to stdout */
+ printf("\necho stub invoke SUCCESSFUL!\n");
+ writer = axis2_xml_writer_create_for_memory(env, NULL, AXIS2_TRUE, 0);
+ om_output = axis2_om_output_create (env, writer);
+
+ AXIS2_OM_NODE_SERIALIZE (ret_node, env, om_output);
+ buffer = AXIS2_XML_WRITER_GET_XML(writer, env);
+ printf ("\nReceived OM node in XML : %s\n", buffer);
+ AXIS2_OM_OUTPUT_FREE(om_output, env);
+ AXIS2_FREE((*env)->allocator, buffer);
+
+ isComplete = 1;
+ return AXIS2_SUCCESS;
+}
+
+axis2_status_t
+my_on_error(struct axis2_callback *callback,
+ axis2_env_t **env,
+ int exception)
+{
+ /** take necessary action on error */
+
+ printf("my on_error error code:%d ::%s", exception,
+ AXIS2_ERROR_GET_MESSAGE((*env)->error));
+ isComplete = 1;
+ return AXIS2_SUCCESS;
}
Modified: webservices/axis2/trunk/c/xdocs/docs/userguide2.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/xdocs/docs/userguide2.html?rev=392213&r1=392212&r2=392213&view=diff
==============================================================================
--- webservices/axis2/trunk/c/xdocs/docs/userguide2.html (original)
+++ webservices/axis2/trunk/c/xdocs/docs/userguide2.html Fri Apr 7 01:35:38 2006
@@ -625,25 +625,39 @@
services. Axis2 provides a callback based non-blocking API for users.</p>
<p>A Sample demonstrating this senario can be found in the
-samples/client/echo_non_blocking folder. In fact, this sample demonstrates
-one level below the usual callback mechanism.</p>
+samples/client/echo_non_blocking folder. </p>
-<p>Before we look at the code changes to the Echo Blocking Client,, let's get
-a feel of how it works. First You need to create a callback instance using
-axis2_callback_create(axis2_env_t*) and then call the macro
-AXIS2_CALL_INVOKE_NON_BLOCKING(axis2_call_t*, axis2_env_t**,
-axis2_msg_ctx_t*, axis2_callback_t*). In your code, you need to poll using
-the macro AXIS2_CALLBACK_GET_COMPLETE(axis2_callback_t*, axis2_env_t**) to
-check for the completion. Once this macro is true, you can access the reply
-SOAP payload using the macro AXIS2_CALLBACK_GET_ENVELOPE(axis2_callback_t*,
-axis2_env_t**).</p>
+<p>Before we look at the code changes to the Echo Blocking Client, let's get
+a feel of how it works. You need to follow the following steps.<br>
+<ul>
+<li>
+Create a callback instance using
+<font face="Monospace">axis2_callback_create(axis2_env_t*)</font>.</li>
+<li> Define your own on_complete function and set it to the callback object using the macro <font face="Monospace">AXIS2_CALLBACK_SET_ON_COMPLETE(axis2_callback_t *, on_complete_func_ptr).</font> <br> Your callback function should follow the following signature.<br>
+axis2_status_t your_function(axis2_callback *, axis2_env_t **);<br>
+A typedef for this function, <font face="Monospace">on_complete_func_ptr</font> is defined in axis2_callback.h.
+</li>
+<li> Define your own on_error callback function and set it to the callback object using the macro <font face="Monospace">AXIS2_CALLBACK_SET_ON_ERROR(axis2_callback_t *, on_error_func_ptr).</font> <br> Your callback function should follow the following signature. <br>
+<font face="Monospace">axis2_status_t your_function(axis2_callback_t *, axis2_env_t **, int);</font><br>
+A typedef for this function, <font face="Monospace">on_error_func_ptr</font> is defined in axis2_callback.h.
+</li>
+<li> Call the macro<br>
+<font face="Monospace">AXIS2_CALL_INVOKE_NON_BLOCKING(axis2_call_t*, axis2_env_t**,
+axis2_msg_ctx_t*, axis2_callback_t*) </font><br>to access the operation in asyncronous fashion.
+</li>
+<li> That's all you need to do to invoke the web service. Now you need to flesh out your on_complete callback function to do whatever you want to do with the response message.<br>
+You can access the SOAP response message using the following macro. <br>
+<font face="Monospace">AXIS2_CALLBACK_GET_ENVELOPE(axis2_callback_t*,
+axis2_env_t**);</font>
+</li>
+</ul></p>
<p></p>
<p>You need to primarily replace the following portion of code in the Echo
Blocking Client</p>
-<p> stub = <font
+<p><font face="Monospace"> stub = <font
color="#000000">axis2_stub_create_with_endpoint_uri_and_client_home</font>(&<font
color="#000000">env</font>, <font color="#000000">address</font>,<br>
<font color="#000000">client_home</font>);<br>
@@ -659,42 +673,124 @@
<font color="#000000">ret_node</font> = <font
color="#000000">axis2_echo_stub_echo</font>(<font
color="#000000">stub</font>, &<font color="#000000">env</font>, <font
-color="#000000">node</font>);</p>
+color="#000000">node</font>);</font></p>
<p></p>
<p>to the following (note that you need to create an instance of
-axis2_callback_t.</p>
+<font face="Monospace">axis2_callback_t</font>).</p>
<p></p>
-<p></p>
-
-<p> <font color="#000000">callback
- = axis2_callback_create</font>(&<font color="#000000">env</font>);<br>
-<font color="#000000"> AXIS2_CALL_INVOKE_NON_BLOCKING</font>(<font
-color="#000000">call</font>, &<font color="#000000">env</font>, <font
-color="#000000">op</font>, <font color="#000000">msg_ctx</font>, <font
-color="#000000">callback</font>);<br>
- <font color="#000000"><b>while</b></font> (!<font
-color="#000000">AXIS2_CALLBACK_GET_COMPLETE</font>(<font
-color="#000000">callback</font>, &<font color="#000000">env</font>))<br>
- {<br>
- <font color="#000000">printf</font>(<font
-color="#FF0000">"sleep(2) till callback complete\n"</font>);<br>
- <font color="#000000"><b>if</b></font> (<font
-color="#000000">count</font>++ > <font color="#0000FF">10</font>)<br>
- <font color="#000000"><b>break</b></font>;<br>
- <font color="#000000">AXIS2_SLEEP</font>(<font
-color="#0000FF">2</font>); <br>
- }<br>
- <font color="#000000">soap_envelope</font> = <font
-color="#000000">AXIS2_CALLBACK_GET_ENVELOPE</font>(<font
-color="#000000">callback</font>, &<font color="#000000">env</font>);<br>
+<p><font face="Monospace">
+ <font color="#808080"><i>/* create the callback object with default<br>
+ on_complete and on_error callback functions*/</i></font><br>
+ <font color="#000000">callback</font> = <font color="#000000">axis2_callback_create</font>(&<font color="#000000">env</font>);<br>
+<br>
+ <font color="#808080"><i>/* set our on_complete fucntion pointer to the callback object */</i></font><br>
+ <font color="#000000">AXIS2_CALLBACK_SET_ON_COMPLETE</font>(<font color="#000000">callback</font>, <font color="#000000">my_on_complete</font>);<br>
+<br>
+ <font color="#808080"><i>/* set our on_error function pointer to the callback object */</i></font><br>
+ <font color="#000000">AXIS2_CALLBACK_SET_ON_ERROR</font>(<font color="#000000">callback</font>, <font color="#000000">my_on_error</font>);<br>
+<br>
+ <font color="#808080"><i>/* invoke the operation and get the control back to the main<br>
+ program immediately (without blocking)*/</i></font><br>
+ <font color="#000000">AXIS2_CALL_INVOKE_NON_BLOCKING</font>(<font color="#000000">call</font>, &<font color="#000000">env</font>, <font color="#000000">op</font>, <font color="#000000">msg_ctx</font>, <font color="#000000">callback</font>);<br>
+<br>
+ <font color="#000000">printf</font>(<font color="#FF0000">"Non blocking call invoked - Control back to Main Program\n"</font>);<br>
+<br>
+ <font color="#808080"><i>/** this is simply to keep the parent thread running<br>
+ until our on_complete or on_error is invoked<br>
+ */</i></font><br>
+ <font color="#000000"><b>while</b></font>(<font color="#0000FF">1</font>)<br>
+ {<br>
+ <font color="#000000"><b>if</b></font> (<font color="#000000">isComplete</font>)<br>
+ {<br>
+ <font color="#808080"><i>/* we are done with the callback */</i></font><br>
+ <font color="#000000"><b>break</b></font>;<br>
+ }<br>
+ }<br>
+<br>
+ </font></p>
+
+<p>
+
+<p> You need to impletement your own on_complete and on_error functions to handle callbacks. A sample implementation is shwon below.</p>
+<p><font face="Monospace">
+<font color="#000000">axis2_status_t</font> <br>
+<font color="#000000">my_on_complete</font>(<font color="#000000"><b>struct</b></font> <font color="#000000">axis2_callback</font> *<font color="#000000">callback</font>,<br>
+ <font color="#000000">axis2_env_t</font> **<font color="#000000">env</font>)<br>
+{<br>
+ <font color="#808080"><i>/** SOAP response has arrived here; get the soap envelope <br>
+ from the callback object and do whatever you want to do with it */</i></font><br>
+ <br>
+ <font color="#000000">axis2_soap_envelope_t</font> *<font color="#000000">soap_envelope</font> = <font color="#000000">NULL</font>;<br>
+ <font color="#000000">axis2_om_node_t</font> *<font color="#000000">ret_node</font> = <font color="#000000">NULL</font>;<br>
+ <br>
+ <font color="#000000">axis2_xml_writer_t</font> *<font color="#000000">writer</font> = <font color="#000000">NULL</font>;<br>
+ <font color="#000000">axis2_om_output_t</font> *<font color="#000000">om_output</font> = <font color="#000000">NULL</font>;<br>
+ <font color="#000000">axis2_char_t</font> *<font color="#000000">buffer</font> = <font color="#000000">NULL</font>;<br>
+ <br>
+ <font color="#000000">printf</font>(<font color="#FF0000">"inside on_complete_callback function\n"</font>);<br>
+ <br>
+ <font color="#000000">soap_envelope</font> = <font color="#000000">AXIS2_CALLBACK_GET_ENVELOPE</font>(<font color="#000000">callback</font>, <font color="#000000">env</font>);<br>
+ <br>
+ <font color="#000000"><b>if</b></font> (!<font color="#000000">soap_envelope</font>)<br>
+ {<br>
+ <font color="#000000">AXIS2_LOG_ERROR</font>((*<font color="#000000">env</font>)-><font color="#000000">log</font>, <font color="#000000">AXIS2_LOG_SI</font>, <font color="#FF0000">"Stub invoke FAILED: Error code:"</font><br>
+ <font color="#FF0000">" %d :: %s"</font>, (*<font color="#000000">env</font>)-><font color="#000000">error</font>-><font color="#000000">error_number</font>,<br>
+ <font color="#000000">AXIS2_ERROR_GET_MESSAGE</font>((*<font color="#000000">env</font>)-><font color="#000000">error</font>));<br>
+ <font color="#000000">printf</font>(<font color="#FF0000">"echo stub invoke FAILED!\n"</font>);<br>
+ <font color="#000000"><b>return</b></font> <font color="#000000">AXIS2_FAILURE</font>;<br>
+ }<br>
+ <br>
+ <font color="#000000">ret_node</font> = <font color="#000000">AXIS2_SOAP_ENVELOPE_GET_BASE_NODE</font>(<font color="#000000">soap_envelope</font>, <font color="#000000">env</font>);<br>
+<br>
+ <font color="#000000"><b>if</b></font>(!<font color="#000000">ret_node</font>)<br>
+ {<br>
+ <font color="#000000">AXIS2_LOG_ERROR</font>((*<font color="#000000">env</font>)-><font color="#000000">log</font>, <font color="#000000">AXIS2_LOG_SI</font>, <font color="#FF0000">"Stub invoke FAILED: Error code:"</font><br>
+ <font color="#FF0000">" %d :: %s"</font>, (*<font color="#000000">env</font>)-><font color="#000000">error</font>-><font color="#000000">error_number</font>,<br>
+ <font color="#000000">AXIS2_ERROR_GET_MESSAGE</font>((*<font color="#000000">env</font>)-><font color="#000000">error</font>));<br>
+ <font color="#000000">printf</font>(<font color="#FF0000">"echo stub invoke FAILED!\n"</font>);<br>
+ <font color="#000000"><b>return</b></font> <font color="#000000">AXIS2_FAILURE</font>;<br>
+ }<br>
+<br>
+ <font color="#808080"><i>/*we just serialize the SOAP message and output to stdout */</i></font><br>
+ <font color="#000000">printf</font>(<font color="#FF0000">"\necho stub invoke SUCCESSFUL!\n"</font>);<br>
+ <font color="#000000">writer</font> = <font color="#000000">axis2_xml_writer_create_for_memory</font>(<font color="#000000">env</font>, <font color="#000000">NULL</font>, <font color="#000000">AXIS2_TRUE</font>, <font color="#0000FF">0</font>);<br>
+ <font color="#000000">om_output</font> = <font color="#000000">axis2_om_output_create</font> (<font color="#000000">env</font>, <font color="#000000">writer</font>);<br>
+<br>
+ <font color="#000000">AXIS2_OM_NODE_SERIALIZE</font> (<font color="#000000">ret_node</font>, <font color="#000000">env</font>, <font color="#000000">om_output</font>);<br>
+ <font color="#000000">buffer</font> = <font color="#000000">AXIS2_XML_WRITER_GET_XML</font>(<font color="#000000">writer</font>, <font color="#000000">env</font>);<br>
+ <font color="#000000">printf</font> (<font color="#FF0000">"\nReceived OM node in XML : %s\n"</font>, <font color="#000000">buffer</font>);<br>
+ <font color="#000000">AXIS2_OM_OUTPUT_FREE</font>(<font color="#000000">om_output</font>, <font color="#000000">env</font>);<br>
+ <font color="#000000">AXIS2_FREE</font>((*<font color="#000000">env</font>)-><font color="#000000">allocator</font>, <font color="#000000">buffer</font>);<br>
+<br>
+ <font color="#000000">isComplete</font> = <font color="#0000FF">1</font>;<br>
+ <font color="#000000"><b>return</b></font> <font color="#000000">AXIS2_SUCCESS</font>;<br>
+}<br>
+<br>
+<font color="#000000">axis2_status_t</font> <br>
+<font color="#000000">my_on_error</font>(<font color="#000000"><b>struct</b></font> <font color="#000000">axis2_callback</font> *<font color="#000000">callback</font>,<br>
+ <font color="#000000">axis2_env_t</font> **<font color="#000000">env</font>,<br>
+ <font color="#800000">int</font> <font color="#000000">exception</font>)<br>
+{<br>
+ <font color="#808080"><i>/** take necessary action on error */</i></font><br>
+<br>
+ <font color="#000000">printf</font>(<font color="#FF0000">"my on_error error code:%d ::%s"</font>, <font color="#000000">exception</font>, <br>
+ <font color="#000000">AXIS2_ERROR_GET_MESSAGE</font>((*<font color="#000000">env</font>)-><font color="#000000">error</font>));<br>
+ <font color="#000000">isComplete</font> = <font color="#0000FF">1</font>;<br>
+ <font color="#000000"><b>return</b></font> <font color="#000000">AXIS2_SUCCESS</font>;<br>
+}<br>
+<br>
+ </font></p>
+<p> There are situation where you may need to keep data pertaining to each callback you make. You can make use of the following macros in such situations.<br>
+<font face="Monospace">
+ <font color="#000000">AXIS2_CALLBACK_SET_DATA</font>(<font color="#000000">axis2_callback_t</font> *, <font color="#800000">void</font> *);<br>
+ <font color="#000000">AXIS2_CALLBACK_GET_DATA</font>(<font color="#000000">axis2_callback_t</font> *);<br>
+ </font><br><br>
+Please refer to the sample shipped with the release to see the complete working code.
</p>
-
-<p></p>
-
<p align="right"><a href="userguide1.html"><img src="images/arrow_left.gif">
Previous</a> | <a href="userguide3.html">Next <img
src="images/arrow_right.gif"></a></p>