Getting started with integrated Web services client for ILE
The integrated Web services client for ILE allows client applications written in an ILE programming language such as RPG, COBOL, C and C++ to access Web services.
This article provides a quick example of how to create a Web services client application written in ILE RPG. Since the example relies on the ConvertTemp service, you will need to create Web services server as described in Learn Web services server (when creating the Web services server, you do not need to deploy a Web service, we will be using the sample Web service that gets deployed automatically when a server is created).
Note: The installation directory for Web Services Client for ILE is /QIBM/ProdData/OS/WebServices/V1/client. In this article the installation directory is shown as <inst_dir>.
Before you can create a web service client application, you must first generate the client stubs using the wsdl2ws.sh tool. The wsdl2ws.sh tool uses the WSDL file that is passed to it, and any associated XSD files, to create client stubs.
We will be using the ConvertTemp.wsdl file located in directory <inst_dir>/samples/ConvertTemp, which is the WSDL file for the sample ConvertTemp service that is automatically deployed when an integrated Web services server is created. This very simple sample provides a good introduction to using wsdl2ws.sh. To generate the client stubs from your WSDL source file, complete the following steps.
- Start a Qshell session by issuing the QSH CL command from the CL command line.
- Run the wsdl2ws.sh tool to generate the client stubs as shown below:
/QIBM/ProdData/OS/WebServices/V1/client/bin/wsdl2ws.sh
-lc -o/myconverttemp
/QIBM/ProdData/OS/WebServices/V1/client/samples/ConvertTemp/ConvertTemp.wsdl
The command above will generate C stubs files in the /myconverttemp directory. Figure 1 below shows you the contents of the directory:
Figure 1. Generated stub files
At this point let us take a look at what is generated (more details on what is generated can be found by going to the Documentation page). If you look at the ConvertTemp.wsdl file, you will find that there is one service defined, ConvertTemp, which has one port type (wsdl:portType) , ConvertTempPortType. A port type is a named set of abstract operations and the abstract messages involved. The name of the wsdl:portType will be used in the names of the Web service proxy (termed service interface) functions. A port type is mapped to four functions:
| Function name |
Description |
| get_ <portType-name>;_stub |
Function that is used to get an object representing the service interface (i.e. the Web service proxy stub). The type of the object is AXISCHANDLE, which is defined as a void pointer (i.e. void *). The AXISCHANDLE is used by Axis to represent different objects so one must be sensitive to what the object represents. In this case the object is the interface to the Axis engine. The operations that can be performed on the object are listed in the <install-dir>/include/axis/client/Stub.h header file. |
| destroy_ <portType-name>;_stub |
Function used to destroy service interface objects that are obtained by invoking get_ <portType-name>;_stub. |
| get_ <portType-name>;_Status |
Function used to get the status of last Web service operation. |
| set_ <portType-name>;_ExceptionHandler |
Function used to set the exception (i.e. SOAP fault) handler for the service interface. |
Now let us look at a concrete example by getting back to the ConvertTemp.wsdl file and seeing how the wsdl:portType (shown below) gets mapped.
<wsdl:portType name="ConvertTempPortType">
<wsdl:operation name="converttemp_XML">
<wsdl:input message="axis2:converttemp_XMLRequest"
wsaw:Action="urn:converttemp_XML"/>
<wsdl:output message="axis2:converttemp_XMLResponse"
wsaw:Action="urn:converttemp_XMLResponse"/>
</wsdl:operation>
<wsdl:operation name="converttemp">
<wsdl:input message="axis2:converttempRequest"
wsaw:Action="urn:converttemp"/>
<wsdl:output message="axis2:converttempResponse"
wsaw:Action="urn:converttempResponse"/>
</wsdl:operation>
</wsdl:portType>
The wsdl2ws.sh tool generated the following C functions (defined and implemented by the ConvertTempPortType.h and ConvertTempPortType.c files):
AXISCHANDLE get_ConvertTempPortType_stub(const char* pchEndPointUri);
void destroy_ConvertTempPortType_stub(AXISCHANDLE pStub);
int get_ConvertTempPortType_Status(AXISCHANDLE pStub);
void set_ConvertTempPortType_ExceptionHandler(AXISCHANDLE pStub,
AXIS_EXCEPTION_HANDLER_FUNCT fp);
xsdc__string converttemp_XML(AXISCHANDLE pStub,
CONVERTTEMPInput* Value0);
CONVERTTEMPResult* converttemp(AXISCHANDLE pStub,
CONVERTTEMPInput* Value0);
The first four C functions shown above are the functions that are generated in support of the service interface. You see how the wsdl:portType name ConvertTempPortType is used in the naming of the functions. One thing to note about the get_ConvertTempPortType_stub() function, and that is the default URL to the Web service will be used if get_ConvertTempPortType_stub() is invoked with a NULL value for endpoint parameter. The default URL is whatever is specified in the wsdl:port WSDL definition.
The last 2 C functions shown, converttemp_XML() and converttemp(), are mapped from the wsdl:operation element defined in the wsdl:portType. The first parameter, pStub, is an opaque pointer representing the web service interface that is obtained by invoking the get_ConvertTempPortType_stub() function. The input parameter data type, CONVERTTEMPInput, is defined and implemented by CONVERTTEMPInput.h and CONVERTTEMPInput.c, respectively. The result data type, CONVERTTEMPResult, is defined and implemented by CONVERTTEMPResult.h and CONVERTTEMPResult.c, respectively. The important thing to remember about output parameters, which are returned as pointers to storage, is that the storage needs to be freed by the client application. So if you looked at CONVERTTEMPResult.h, you would see the following:
typedef struct CONVERTTEMPResultTag {
xsdc__string _TEMPOUT;
} CONVERTTEMPResult;
void Axis_Delete_CONVERTTEMPResult(CONVERTTEMPResult* param,
int nSize);
The CONVERTTEMPResult data type above is defined as a structure that contains a pointer to a string. There is also a function, Axis_Delete_CONVERTTEMPResult(), that is used to release the storage defined by the CONVERTTEMPResult data type. Anytime dynamic storage (i.e. pointer type) is returned, the storage needs to be freed once we are done processing the results. For example, if a Web service client application invoked the converttemp() operation, the result, which is a pointer to CONVERTTEMPResult, should be freed by invoking the Axis_Delete_CONVERTTEMPResult() (when calling the function the second parameter, nSize, should be set to zero).
At this point it is assumed that the generated stubs are in a directory called /myconverttemp. The RPG code that uses the generated stubs is located in <inst_dir>/samples/ConvertTemp/CNVRTTMPC.RPGLE.
To build the CNVRTTEMP client application, complete the following steps from the CL command line.
- Create a library that will contain the module and program objects. In this example, we create a library called CVTTEMP by issuing the following CL command:
CRTLIB CVTTEMP
- Change the current working directory to '/myconverttemp' by issuing the following CL command:
CD '/myconverttemp'
- Copy the RPG code that uses the generated stubs to ?/myconverttemp' by issuing the following CL command:
COPY OBJ('<inst_dir>/samples/converttemp/converttempclient.rpgle')
TODIR('/myconverttemp')
- Update the following line in converttempclient.rpgle so that the host name and port is set to the host name and port of the Web services server. The code currently has host name set to "localhost" and the port set to 10000.
Endpoint = 'http://localhost:10000/web/services/ConvertTemp' + X'00';
- Build the client application using the following commands.
CRTRPGMOD MODULE(CVTTEMP/CVTTEMPCL)
SRCSTMF(ConvertTempClient.RPGLE)
CRTCMOD MODULE(CVTTEMP/CVTTEMPIN)
SRCSTMF('CONVERTTEMPInput.c')
INCDIR('/qibm/proddata/os/webservices/v1/client/include') ENUM(*INT)
CRTCMOD MODULE(CVTTEMP/CVTTEMPRES)
SRCSTMF('CONVERTTEMPResult.c')
INCDIR('/qibm/proddata/os/webservices/v1/client/include') ENUM(*INT)
CRTCMOD MODULE(CVTTEMP/CVTTEMPPT)
SRCSTMF('ConvertTempPortType.c')
INCDIR('/qibm/proddata/os/webservices/v1/client/include') ENUM(*INT)
CRTPGM PGM(CVTTEMP/CNVRTTEMP)
MODULE(CVTTEMP/*ALL) BNDSRVPGM(QSYSDIR/QAXIS10CC)
When you have finished coding and building the web service client application, run and test the client application by completing the following steps.
- Run the client application by issuing the following from the CL command line (in this example we want to find out what 5 degrees Fahrenheit is in Celsius):
CALL CVTTEMP/CNVRTTEMP '5'
- Check that the client application shows the Celsius representation of the Fahrenheit value used above. The example screen shot below in Figure 2 shows the client application run from the command line (note that to see the result you need to press "F10=Include detailed messages" function key):
Figure 2. Calling client application

|