Published on WSO2 Oxygen Tank (http://wso2.org)

Introduction to Axis2/C Service Client API

By dinesh
Created 2008-02-15 20:52

In this article by Dinesh Premalal, he introduces Axis2/C Service Client API for the beginner.

 

Introduction

This article describes, how to develop clients for a given Web services, focusing on Axis2/C Service Client API. A simple, but yet, a comprehensive example is taken to discuss the usage of the client API. Towards the end of the article, I give a brief introduction to some of the most important options that users and developers generally ask for.

 

Applies To

Apache Axis2/C 1.3.0
Service Client API  
Environment Linux - Ubuntu, Debian, Gentoo

Windows

Solaris

 

Background

Axis2/C provides a simple and useful client API to interact with Web services. One can use this service client API or an operational client API to communicate with Web services. In Apache Axis2/C, Service Client API is designed for the use of average users who need to send and receive XML based payloads and the Operation Client API  is, for the more advance user, who deals with SOAP headers etc. In this article, we mainly focus on the service client API which is straight forward and relatively easy to use.

 

Introducing Apache Axis2/C Service Client API

Essentially, there are two ways to interact with Web services:

  1. Generating client stubs using WSDL2C
  2. One can generate client stubs for a particular WSDL using the WSDL2C tool. This is the way most users try out when they do it for the first time. WSDL2C tool is based on Axis2/Java code generation engine.Although the WSDL2Java tool is implemented in Java, It can be used to generate code in any other language.This tool is quite mature now and therefore, we are using it to generate code for Apache Axis2/C

  3. Using Client API
  4. Using client API, one can write comprehensive client codes quite easily. With only the very basic information about service endpoints and payload details, users can communicate with Web services this way. Using different options in Service Client API, users can change the behavior of the client.

 

Service Client API

Service Client API provides a simple and easy mechanism to write client side code for Web services. However, the flexibility in service client API is at a minimum. In order to use the service client, following  is a list of the minimum information users need to be equipped with:

  1. Service EndPoint Address(To Address)
  2. Message Payload
  3. Client Repository

Service Endpoint Address is the address of the service that user needs to interact with. This end point could be based on any transport (HTTP, HTTPS, TCP, XMPP) that is supported by the Axis2/C SOAP engine.

Message Payload is the content of the message a user plans on sending to the server. This message is the input, the user gives to the service. Since the basic building block of Axis2/C engine is an axiom node, users need to give this node as an axiom node. Once you have the XML payload in hand, you just need to parse it using Axiom to create an axiom node.

Client Repository is required for the Axis2/C engine to find out about its configuration. Basic configuration file is axis2.xml and contains many pointers regarding configuration. There are some configurations in which we could use the Service Client API instead of axis2.xml , however, there are sets of configurations such as Axis2/C Flow and Phases configuration that comes only with axis2.xml

 

How to Use the Service Client

1.  const axutil_env_t *env = NULL;
      2.  const axis2_char_t *address = NULL;
      3.  axis2_endpoint_ref_t *endpoint_ref = NULL;
      4.  axis2_options_t *options = NULL;
      5.  const axis2_char_t *client_home = NULL;
      6.  axis2_svc_client_t *svc_client = NULL;
      7.  axiom_node_t *payload = NULL;
      8.  axiom_node_t *ret_node = NULL;
      9.
      10.  env = axutil_env_create_all("echo.log", AXIS2_LOG_LEVEL_TRACE);
      11.  address = "http://localhost:9090/axis2/services/echo";
      12.  endpoint_ref = axis2_endpoint_ref_create(env, address);
      13.  options = axis2_options_create(env);
      14.  axis2_options_set_to(options, env, endpoint_ref);
      15.  client_home = AXIS2_GETENV("AXIS2C_HOME");
      16.  svc_client = axis2_svc_client_create(env, client_home);
      17.  axis2_svc_client_set_options(svc_client, env, options);
      18.  payload = build_om_payload_for_echo_svc(env);
      19.  ret_node = axis2_svc_client_send_receive(svc_client, env, payload);

line 1-8 : defines variables that will be used later on within the code.

line 10 : creating basic environment. That environment carries pointers to error handlers, memory allocator, logger and etc. At this point we give the name of the log file and the required log level.

line 11-12: creating endpoint reference using  Webservice endpoint. This is the address at which the service is actually available

line 13: creating options structure, these options are used to pass options to Axis2/C engine.

line 14: Setting TO address as an option to be passed to the engine. Different options that can be used to have different features will be discussed later on in this article.

line 15: obtaining the value of the client repository using AXIS2C_HOME environment variable. This does not have to be via the environment variable. One could specify an absolute or relative path to the client repository. Client repository is important to load relevant configuration.

Line 16: creating service client (svc_client) , passing environment and client_home as arguments. We then use this svc_client to deal with our Web service.

Line 17: Passing options to svc_client, making them available for the Axis2/C engine.

Line 18: Building payload. This is the exact location at which the code gets access to the input for the Web service the client is expected to interact with. Here we provide payload as an axiom node.

Line 19: using axis2_svc_client_send_receive, client sends out the request for the service and awaits for a response. This is the send/receive model. There maybe situations that only need to send out a request but do not need to wait for a response and in that case we could use axis2_svc_client_fire_and_forget. There is no possibility to receive an error while using this method. If user needs to send a request and get informed only when an error occurs, we could use axis2_svc_client_send_robust method.

 

More on Send/Receive Functions

Asynchronous Messages

If a user chooses to, he could use these send/receive methods to deal with the Web service in an asynchronous manner:

callback = axis2_callback_create(env);
        axis2_callback_set_on_complete(callback, echo_callback_on_complete);
        axis2_callback_set_on_error(callback, echo_callback_on_error);
        axis2_svc_client_send_receive_non_blocking(svc_client, env,
                                                  payload, callback);

After creating the callback structure a user can register with the two callbacks, one on_complete and the other, on_error. These callbacks will then be invoked during send/receive, either upon completion or in the instance an error is encountered.

 

Dual Channel

In the earlier scenario, both the request and response used the same channel. It is also possible to use one channel to send a request, and another, to receive the response. Under these circumstances users need to specify the receiving channel using axis2.xml.

axis2_options_set_use_separate_listener(options, env, AXIS2_TRUE);
    axis2_options_set_action(options, env,
    "http://ws.apache.org/axis2/c/samples/echoString");
    reply_to = axis2_endpoint_ref_create(env,
    "http://localhost:6060/axis2/services/__ANONYMOUS_SERVICE__/__OPERATION_OUT_IN__");
    axis2_options_set_reply_to(options, env, reply_to);

In the case of dual channels, users set separate listener flags in options to TRUE and reply-to address in WS-Addressing to __ANONYMOUS_SERVICE__ endpoint. Before we do this, we need to engage the WS-Addressing module.

 

Engaging a Module

A module is a set of handlers that helps to extend the message processing behavior of the Axis2/C engine. Modules have the concepts of being available and engaged associated with them. Available means modules are deployed in the system but not activated.Before using any functionality available as a module, we need to first engage it. Engaging a module can be done in two different ways. One is using the axis2.xml and other one using service client api.

 

Sending Attachments with MTOM

One of the remarkable features of Axis2/C engine is the ability to send binary attachments. Those attachments can be sent in both optimized and non-optimized forms. When sending attachments using MTOM, users need to enable MTOM using either axis2.xml or service client api.

sending requests with an MTOM attachment might be bit different to other requests, in that users need to use axiom_data_handler for reading and sending the attachment.

 

SOAP 1.2 and SOAP 1.1

Although default behaviour is set to SOAP 1.2 , users can switch between SOAP 1.2 and SOAP 1.1 setting an option in the service client. This option is important for maintaining backward compatibility. There are many services out there that are deployed in SOAP 1.1 and still users can use Axis2/C Service Client API for writing clients for those services.

axis2_options_set_soap_version(options, env, AXIOM_SOAP11);

Although Apache Axis2/C processes SOAP messages, it is also capable of exposing services in a RESTful way.

 

REST Invocation

Before using the service client to consume REST services, users need to let the engine know about it. In order to do this , user have two options:

 

Summary

In this article, I've made an effort to give an introduction to Axis2/C Service Client API. In addition, I have explained details on using some important features of the Service Client API.

 

References

  1. Axis2/C Manual, Service Client API [1]
  2. Apache Axis2/C - Web services Engine [2]
  3. Quick Introduction to Axis2 Client API [3]

 

Author

Dinesh Premalal, Senior Software Engineer at WSO2 and Apache committer for Apache Axis2/C. dinesh AT wso2 DOT com


Source URL:
http://wso2.org/library/3238