Web Services in CANIAS
a. Web Service operations and prototypes
Web Service operations that can be called in CANIAS are :
i. Login
This is a typical operation that is used to login to a CANIAS application server. Its prototype is:
public String Login(String client,String langu,String db,
String dbserver,String appserver,String user,String pass) throws RemoteException;
As the prototype tells that its arguments are the same as a Client Login Dialog.
ii. listIASServices
This operation is used to list all available CANIAS web services ( function of a class) that may be called as a web service . Each CANIAS web service is a function of a CANIAS class. To use this call, user has to be logged in. This call may return different results based on the user calling this function. Its prototype is:
public String[] listIASServices(String clientConnID) throws RemoteException;
The function takes the result returned from Login call as argument. The function returns a string array. Each item is constructed of a CANIAS service name (function of a class) and its description. For example ; CANIAS service name is ‘paramtest’ and its description is ‘parameter test’ . This call will return ‘paramtest_parameter test ‘ as one of the items.
This call uses two tables . One is IASWEBSERVICES and the other is IASWSRIGHTS.
The former is used to store relations between CANIAS web service names and CANIAS class functions. Consider the example above, the CANIAS web service ‘paramtest’ is just a name to simplify the call, which function it will invoke is kept in IASWEBSERVICES table. The latter table is an authorization table that gives information on the caller id.
iii. callIASService
This operation is used to invoke the CANIAS web service. Its prototype is:
public Object callIASService(String clientConnID,String serviceID,
String args,String returnType) throws RemoteException;
The first two arguments can be obtained by the calls above. The third is the comma seperated parameter list that will be used by a CANIAS class function. This parameter list will be passed as the parameters of a CANIAS function. Consider a CANIAS function named ‘paramtst’ which has a body like the one below:
PARAMETERS:
DATE DT1,
STRING S1,
INTEGER I1,
DECIMAL D1;
OBJECT:
DATE MDT1,
STRING MS1,
INTEGER MI1,
DECIMAL MD1;
MDT1 = DT1;
MS1 = S1;
MI1 = I1;
MD1 = D1;
RETURN MD1;
Assume that this class is defined as a CANIAS web service named ‘paramtest’. To call this CANIAS service, the real web service invoked with the parameters :
Param1 : USER_xxx
Param2 : paramtest
Param3 : 01.01.2005, AAA,13,17.45
Param4 : DECIMAL
Parameter3 will be parsed on commas and related CANIAS parameters will be passed to function. The return type ‘Object’ indicates that every CANIAS function may have different return types.
At this point one may come with the question ‘how to know what is the return type or what are the parameters to be passed to the CANIAS service?’. True. Because a CANIAS function is hidden to a web service consumer, the description info of the service that will be returned by listIASServices function must be well defined.
iv. Logout
This is a typical operation that is used to logout from a CANIAS application server. Its prototype is:
public void Logout(String clientConnID) throws RemoteException;
b. How to call CANIAS Web Service
The name of the CANIAS web service as defined in its WSDL file is ‘iasWebService’. The soap messages below can be used to call the service operations defined above.
i. Calling ‘Login’ operation
Request:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:Login>
<String_1 xsi:type="xsd:string">00</String_1>
<String_2 xsi:type="xsd:string">T</String_2>
<String_3 xsi:type="xsd:string">IAS602</String_3>
<String_4 xsi:type="xsd:string">localhost</String_4>
<String_5 xsi:type="xsd:string">localhost</String_5>
<String_6 xsi:type="xsd:string">BUGRA</String_6>
<String_7 xsi:type="xsd:string">IAS</String_7>
</ns0:Login>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:LoginResponse>
<result xsi:type="xsd:string">BUGRA_40000002</result>
</ns0:LoginResponse>
</env:Body>
</env:Envelope>
ii. Calling ‘listIASServices’ operation
Request :
(Notice that String_1 arg is what is returned from the Login call)
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:listIASServices>
<String_1 xsi:type="xsd:string">BUGRA_40000002</String_1>
</ns0:listIASServices>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:listIASServicesResponse><result href="#ID1"/>
</ns0:listIASServicesResponse>
<ns0:ArrayOfstring id="ID1" xsi:type="enc:Array" enc:arrayType="xsd:string[2]">
<item xsi:type="xsd:string">ECHOTEST_ECHO TEST</item>
<item xsi:type="xsd:string">PARAMTEST_Parameters test</item>
</ns0:ArrayOfstring>
</env:Body>
</env:Envelope>
iii. Calling ‘callIASService’ operation.
Request:
(The function we call just echoes)
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:callIASService>
<String_1 xsi:type="xsd:string">BUGRA_40000002</String_1>
<String_2 xsi:type="xsd:string">ECHOTEST</String_2>
<String_3 xsi:type="xsd:string">HELLO WEB SERVICES</String_3>
<String_4 xsi:type="xsd:string">STRING</String_4>
</ns0:callIASService>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:callIASServiceResponse>
<result xsi:type="xsd:string"> Echo from class : HELLO WEB SERVICES</result>
</ns0:callIASServiceResponse>
</env:Body>
</env:Envelope>
iv. Calling ‘Logout’ operation.
Request:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:Logout>
<String_1 xsi:type="xsd:string">BUGRA_40000002</String_1>
</ns0:Logout>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:LogoutResponse/>
</env:Body>
</env:Envelope>
c. How to call a Web Service using TROIA.
To call a web service, the web server that is queried (with the url given ) must be up and active.
i. Using HTTP-POST
By using SENDHTTPPOST command, a web service can be called using TROIA. ( Do not forget to set content type to ‘text/xml’)
OBJECT:
STRING S,
STRING CTYPE;
CTYPE = ‘text/xml’;
S = 'http://localhost:8080/iasWebService/iasWebService';
SENDHTTPPOST STRINGVAR3 TO S CONTENTTYPE CTYPE ;
INTEGERVAR3 = SYS_STATUS;
RESULTBOX = SYS_HTTPPOSTRESPONSE;
The variable STRINGVAR3 must be one of the soap requests above. The response will be stored in SYS_HTTPPOSTRESPONSE .
ii. Using Dynamic Invocation Interface.
With this technique, the wsdl is parsed and the desired operation is invoked dynamically given its parameters. The parameters given are converted into a soap envelope which is then sent to address given. The operation and parameters have to be gathered from wsdl definitions. To use this technique, TROIA serves us a command named ‘CALLWEBSERVICE’. Its usage is .
CALLWEBSERVICE wsdladdress , operation TO sym WITH params(comma seperated values)
The code below invokes the same function as sending soap message to ‘callIASService’.
OBJECT:
STRING WSDLADDR,
STRING OPERATION,
STRING PRM1,
STRING PRM2,
STRING PRM3,
STRING PRM4;
WSDLADDR = ‘http://localhost:8080/iasWebService/iasWebService?WSDL’;
OPERATION = 'callIASService';
PRM1 = 'BUGRA_40000002';
PRM2 = 'PARAMTEST';
PRM3 = '01.01.2005,WWW,12,34.745';
PRM4 = 'DECIMAL';
CALLWEBSERVICE WSDLADDR, OPERATION TO STRINGVAR3 WITH PRM1,PRM2,PRM3,PRM4;
The result, which is also a soap envelope, will be stored in STRINGVAR3.
The example above shows a web service operation that uses primitive types as parameters but what happens when the parameters are of complex types. Look at the definition of an operation in a web service wsdl below ( url http://mssoapinterop.org/asmx/xsd/round4XSD.asmx?op=echoComplexType )
POST /asmx/xsd/round4XSD.asmx HTTP/1.1
Host: mssoapinterop.org
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://soapinterop.org/echoComplexType"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<echoComplexType xmlns="http://soapinterop.org/">
<inputComplexType>
<varInt xmlns="http://soapinterop.org/xsd">int</varInt>
<varString xmlns="http://soapinterop.org/xsd">string</varString>
<varFloat xmlns="http://soapinterop.org/xsd">float</varFloat>
</inputComplexType>
</echoComplexType>
</soap:Body>
</soap:Envelope>
It is obvious that this operation needs a complex type of three elements inside. To match the requirements of these complex types, developers in TROIA have to use tables. The table used must contain two columns with predefined column names LOCALNAME and VALUE. LOCALNAME column must contain the same the element names (varInt,varFloat,varString) used inside the complex type(inputComplexType). Consider the code below :
OBJECT:
STRING WSDLADDR,
STRING OPERATION,
TABLE QTAB;
CLEAR ALL QTAB;
/* columns must have these names
APPEND COLUMN LOCALNAME,STRING,40 TO QTAB;
APPEND COLUMN VALUE,STRING,40 TO QTAB;
*
/
APPEND ROW TO QTAB;
MOVE 'varInt' TO QTAB_LOCALNAME;
MOVE '5' TO QTAB_VALUE;
APPEND ROW TO QTAB;
MOVE 'varString' TO QTAB_LOCALNAME;
MOVE 'ddd' TO QTAB_VALUE;
APPEND ROW TO QTAB;
MOVE 'varFloat' TO QTAB_LOCALNAME;
MOVE '3.0' TO QTAB_VALUE;
WSDLADDR = 'http://mssoapinterop.org/asmx/xsd/round4XSD.wsdl';
OPERATION = 'echoComplexType';
CALLWEBSERVICE WSDLADDR,OPERATION TO STRINGVAR3 WITH QTAB;
The envelope send whih can be seen by the trace:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<echoComplexType xmlns="http://soapinterop.org/">
<inputComplexType xmlns="http://soapinterop.org/">
<varInt xmlns="http://soapinterop.org/xsd">5</varInt>
<varString xmlns="http://soapinterop.org/xsd">ddd</varString>
<varFloat xmlns="http://soapinterop.org/xsd">3.0</varFloat>
</inputComplexType>
</echoComplexType>
</soapenv:Body>
</soapenv:Envelope>
The response from the service called, will also be stored as a soap envelope in STRINGVAR3:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<echoComplexTypeResponse xmlns="http://soapinterop.org/">
<return>
<varInt xmlns="http://soapinterop.org/xsd">5</varInt>
<varString xmlns="http://soapinterop.org/xsd">ddd</varString>
<varFloat xmlns="http://soapinterop.org/xsd">3</varFloat>
</return>
</echoComplexTypeResponse>
</soap:Body>
</soap:Envelope>
d. Finding Web Services
Up to now, this document dealt with how to produce and consume web services. Finding a web service throughout an XML registry is another significant feature used by web service developers and consumers. XML registries can be thought of as an electronic yellow pages where producers and consumers dynamically discover one another. TROIA supports querying XML registries with QUERYXMLREGISTRY function for a specific web service
OBJECT:
STRING UDDIREG,
STRING UDDIREGM,
STRING SERVICE,
STRING PHOST,
STRING PPORT;
UDDIREG = 'http://uddi.ibm.com/testregistry/inquiryapi';
UDDIREGM = 'http://test.uddi.microsoft.com/inquire';
SERVICE = '%WEATHER%';
PHOST = '192.168.0.196';
PPORT = '3128';
INTEGERVAR2 = QUERYXMLREGISTRY(UDDIREG,SERVICE,PHOST,PPORT);.
The code above queries the test registry provided by IBM (or Microsoft) for the services with the name ‘like(%) WEATHER’ . The last two parameters are optional for proxy host and port of the machine where CANIAS application server resides not the client. The integer returned shows the number of services that matches. This function not only returns the number of results found but the names and their access points as well in a table called SYSUDDIREGISTRY.
Developers of TROIA may consume a web service throughout this table as told in part c .
e. How to compile and deploy web services.
iasWebService is an rpc(remote process call) type service.
i. Compiling
The classes used are; iasWebServiceIF (interface) , iasWebServiceImpl (implementation), iasWebServiceHandler (a class used to store remote server stubs by the help of a static hashtable) and found in package ‘com.ias.web’. The interface file extends Remote class of java.
public interface iasWebServiceIF extends Remote {
.....
}
This interface will be used by the ‘wsdeploy’ tool to create rpc stubs and tie objects.
Compiling is done as usual with the classes explained above.
ii. Packaging and Deployment
Besides the classes, final deployment needs extra description files. These are ‘jaxrpc-ri.xml’ and ‘web.xml’ . The first file is a description file for iasWebService. Its content is:
<?xml version="1.0" encoding="UTF-8"?>
<webServices
xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/dd"
version="1.0"
targetNamespaceBase="urn:Foo"
typeNamespaceBase="urn:Foo"
urlPatternBase="/ws">
<endpoint
name="iasWebService"
displayName="Canias Web Service"
description="Canias Web service"
interface="com.ias.web.iasWebServiceIF"
implementation="com.ias.web.iasWebServiceImpl"/>
<endpointMapping
endpointName="iasWebService"
urlPattern="/iasWebService"/>
</webServices>
The second file is a standard web info file.
These two file must reside in a directory called ‘WEB-INF’. There is another directory called ‘classes’ is also needed. The necessary classeses ( classes compiled above and their dependants) must go under classes directory. Cause package info has to be preserved. The directory structure is shown below:
-- WEB-INF
-- jaxrpc-ri.xml
-- web.xml
-- classes
-- com
-- ias
-- globals
-- server
-- util
-- web
All com.ias packages and classes are not needed , all needed files are:
com.ias.globals:
iasEncryptDecrypt.class
iasRPCDocument.class
iasSeperators.class
XAction.class
Xparameter.class
com.ias.server:
iasServerManagerInterface.class
iasServerManagerRemoteObject_Stub.class
com.ias.util:
iasCompressor.class
com.ias.web:
iasWebServiceIF.class
iasWebServiceImpl.class
iasWebServiceHandler.class
After the directory structure is formed as explained above, ‘war’ package can be formed. Build an archive or use jar(jar cvf ..) command that will contain the classes and files above without loosing path infos into a war named ‘iasTempWebService’. This is a pre-deployment war so we named it as temporary file.
Now it is time for final deployment . ‘wsdeploy’ tool is needed in this stage. Usually it is shipped with jwsdp-1.3 ( Sun Java Web Services Development pack). A batch file ‘wsdeploy.bat‘ is found under ‘C:\jwsdp-1.3\jaxrpc\bin‘ .( It is assumed that jwsdp is founded under C:\ ). This tool creates stubs and ties and more important a ‘wsdl‘ file to describe our web service based on jaxrpc-ri.xml and others.Apply this tool to our intermediate war:
C:\jwsdp-1.3\jaxrpc\bin\wsdeploy.bat -o iasWebService.war iasTempWebService.war
This creates the final war ‘iasWebService.war’ . Copy this file to ‘webapps’ directory of your web server. Start your web server ( Tomcat for instance ) and test it. For example:
http://localhost:8080/iasWebService/iasWebService?WSDL
As it is seen these url matches with the content of our jaxrpc-ri.xml file. Every deployment needs web server to be restarted.
All the things that are told in ‘packaging and deployment’ section can also be made with ant tool. (Ant is sth like linux makefile )
f. What ‘s more .
i. Tables in ODBA
As discussed above two tables in CANIAS is needed. Their specification taken from CANIAS ODBA is below:
DROP TABLE IASWEBSERVICES;
CREATE TABLE IASWEBSERVICES (
CLIENT VARCHAR(2) NOT NULL,
SERVICENAME VARCHAR(20) NOT NULL,
SERVICECLASS VARCHAR(20) NOT NULL,
SERVICEFUNC VARCHAR(30) NOT NULL,
STEXT TEXT
) ;
CREATE UNIQUE INDEX IASTR_001 ON IASWEBSERVICES (CLIENT,SERVICENAME,SERVICECLASS,SERVICEFUNC);
DROP TABLE IASWSRIGHTS;
CREATE TABLE IASWSRIGHTS (
CLIENT VARCHAR(2) NOT NULL,
USERNAME VARCHAR(12) NOT NULL,
SERVICENAME VARCHAR(20) NOT NULL
) ;
CREATE UNIQUE INDEX IASTR_001 ON IASWSRIGHTS (CLIENT,USERNAME,SERVICENAME);
ii. Jars and packages
Download Java Web Services Developer Pack 1.3 from Sun. Also wsdl4j.jar,jaxrpc.jar,axis.jar,saaj.jar,commons-discovery.jar,commons-logging.jar, uddi4j.jar need to be added to project. These jars are found under C:\jwsdp-1.3\common\lib or JBuilderX\lib. Check for them.
One more extra jar must be added to C:\jwsdp-1.3\common\lib directory. That is soap.jar found in /resources/lib of pegasus project path. That file is used for ‘Base64Encoding’ functions. (Restart web server after copying it)
iii. Error tracing
Error logs are found under C:\jwsdp-1.3\logs\ launcher.server.log .
Web Services in CANIAS
a. Web Service operations and prototypes
Web Service operations that can be called in CANIAS are :
i. Login
This is a typical operation that is used to login to a CANIAS application server. Its prototype is:
public String Login(String client,String langu,String db,
String dbserver,String appserver,String user,String pass) throws RemoteException;
As the prototype tells that its arguments are the same as a Client Login Dialog.
ii. listIASServices
This operation is used to list all available CANIAS web services ( function of a class) that may be called as a web service . Each CANIAS web service is a function of a CANIAS class. To use this call, user has to be logged in. This call may return different results based on the user calling this function. Its prototype is:
public String[] listIASServices(String clientConnID) throws RemoteException;
The function takes the result returned from Login call as argument. The function returns a string array. Each item is constructed of a CANIAS service name (function of a class) and its description. For example ; CANIAS service name is ‘paramtest’ and its description is ‘parameter test’ . This call will return ‘paramtest_parameter test ‘ as one of the items.
This call uses two tables . One is IASWEBSERVICES and the other is IASWSRIGHTS.
The former is used to store relations between CANIAS web service names and CANIAS class functions. Consider the example above, the CANIAS web service ‘paramtest’ is just a name to simplify the call, which function it will invoke is kept in IASWEBSERVICES table. The latter table is an authorization table that gives information on the caller id.
iii. callIASService
This operation is used to invoke the CANIAS web service. Its prototype is:
public Object callIASService(String clientConnID,String serviceID,
String args,String returnType) throws RemoteException;
The first two arguments can be obtained by the calls above. The third is the comma seperated parameter list that will be used by a CANIAS class function. This parameter list will be passed as the parameters of a CANIAS function. Consider a CANIAS function named ‘paramtst’ which has a body like the one below:
PARAMETERS:
DATE DT1,
STRING S1,
INTEGER I1,
DECIMAL D1;
OBJECT:
DATE MDT1,
STRING MS1,
INTEGER MI1,
DECIMAL MD1;
MDT1 = DT1;
MS1 = S1;
MI1 = I1;
MD1 = D1;
RETURN MD1;
Assume that this class is defined as a CANIAS web service named ‘paramtest’. To call this CANIAS service, the real web service invoked with the parameters :
Param1 : USER_xxx
Param2 : paramtest
Param3 : 01.01.2005, AAA,13,17.45
Param4 : DECIMAL
Parameter3 will be parsed on commas and related CANIAS parameters will be passed to function. The return type ‘Object’ indicates that every CANIAS function may have different return types.
At this point one may come with the question ‘how to know what is the return type or what are the parameters to be passed to the CANIAS service?’. True. Because a CANIAS function is hidden to a web service consumer, the description info of the service that will be returned by listIASServices function must be well defined.
iv. Logout
This is a typical operation that is used to logout from a CANIAS application server. Its prototype is:
public void Logout(String clientConnID) throws RemoteException;
b. How to call CANIAS Web Service
The name of the CANIAS web service as defined in its WSDL file is ‘iasWebService’. The soap messages below can be used to call the service operations defined above.
i. Calling ‘Login’ operation
Request:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:Login>
<String_1 xsi:type="xsd:string">00</String_1>
<String_2 xsi:type="xsd:string">T</String_2>
<String_3 xsi:type="xsd:string">IAS602</String_3>
<String_4 xsi:type="xsd:string">localhost</String_4>
<String_5 xsi:type="xsd:string">localhost</String_5>
<String_6 xsi:type="xsd:string">BUGRA</String_6>
<String_7 xsi:type="xsd:string">IAS</String_7>
</ns0:Login>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:LoginResponse>
<result xsi:type="xsd:string">BUGRA_40000002</result>
</ns0:LoginResponse>
</env:Body>
</env:Envelope>
ii. Calling ‘listIASServices’ operation
Request :
(Notice that String_1 arg is what is returned from the Login call)
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:listIASServices>
<String_1 xsi:type="xsd:string">BUGRA_40000002</String_1>
</ns0:listIASServices>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:listIASServicesResponse><result href="#ID1"/>
</ns0:listIASServicesResponse>
<ns0:ArrayOfstring id="ID1" xsi:type="enc:Array" enc:arrayType="xsd:string[2]">
<item xsi:type="xsd:string">ECHOTEST_ECHO TEST</item>
<item xsi:type="xsd:string">PARAMTEST_Parameters test</item>
</ns0:ArrayOfstring>
</env:Body>
</env:Envelope>
iii. Calling ‘callIASService’ operation.
Request:
(The function we call just echoes)
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:callIASService>
<String_1 xsi:type="xsd:string">BUGRA_40000002</String_1>
<String_2 xsi:type="xsd:string">ECHOTEST</String_2>
<String_3 xsi:type="xsd:string">HELLO WEB SERVICES</String_3>
<String_4 xsi:type="xsd:string">STRING</String_4>
</ns0:callIASService>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:callIASServiceResponse>
<result xsi:type="xsd:string"> Echo from class : HELLO WEB SERVICES</result>
</ns0:callIASServiceResponse>
</env:Body>
</env:Envelope>
iv. Calling ‘Logout’ operation.
Request:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:Logout>
<String_1 xsi:type="xsd:string">BUGRA_40000002</String_1>
</ns0:Logout>
</env:Body>
</env:Envelope>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="urn:FooiasWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<env:Body>
<ns0:LogoutResponse/>
</env:Body>
</env:Envelope>
c. How to call a Web Service using TROIA.
To call a web service, the web server that is queried (with the url given ) must be up and active.
i. Using HTTP-POST
By using SENDHTTPPOST command, a web service can be called using TROIA. ( Do not forget to set content type to ‘text/xml’)
OBJECT:
STRING S,
STRING CTYPE;
CTYPE = ‘text/xml’;
S = 'http://localhost:8080/iasWebService/iasWebService';
SENDHTTPPOST STRINGVAR3 TO S CONTENTTYPE CTYPE ;
INTEGERVAR3 = SYS_STATUS;
RESULTBOX = SYS_HTTPPOSTRESPONSE;
The variable STRINGVAR3 must be one of the soap requests above. The response will be stored in SYS_HTTPPOSTRESPONSE .
ii. Using Dynamic Invocation Interface.
With this technique, the wsdl is parsed and the desired operation is invoked dynamically given its parameters. The parameters given are converted into a soap envelope which is then sent to address given. The operation and parameters have to be gathered from wsdl definitions. To use this technique, TROIA serves us a command named ‘CALLWEBSERVICE’. Its usage is .
CALLWEBSERVICE wsdladdress , operation TO sym WITH params(comma seperated values)
The code below invokes the same function as sending soap message to ‘callIASService’.
OBJECT:
STRING WSDLADDR,
STRING OPERATION,
STRING PRM1,
STRING PRM2,
STRING PRM3,
STRING PRM4;
WSDLADDR = ‘http://localhost:8080/iasWebService/iasWebService?WSDL’;
OPERATION = 'callIASService';
PRM1 = 'BUGRA_40000002';
PRM2 = 'PARAMTEST';
PRM3 = '01.01.2005,WWW,12,34.745';
PRM4 = 'DECIMAL';
CALLWEBSERVICE WSDLADDR, OPERATION TO STRINGVAR3 WITH PRM1,PRM2,PRM3,PRM4;
The result, which is also a soap envelope, will be stored in STRINGVAR3.
The example above shows a web service operation that uses primitive types as parameters but what happens when the parameters are of complex types. Look at the definition of an operation in a web service wsdl below ( url http://mssoapinterop.org/asmx/xsd/round4XSD.asmx?op=echoComplexType )
POST /asmx/xsd/round4XSD.asmx HTTP/1.1
Host: mssoapinterop.org
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://soapinterop.org/echoComplexType"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<echoComplexType xmlns="http://soapinterop.org/">
<inputComplexType>
<varInt xmlns="http://soapinterop.org/xsd">int</varInt>
<varString xmlns="http://soapinterop.org/xsd">string</varString>
<varFloat xmlns="http://soapinterop.org/xsd">float</varFloat>
</inputComplexType>
</echoComplexType>
</soap:Body>
</soap:Envelope>
It is obvious that this operation needs a complex type of three elements inside. To match the requirements of these complex types, developers in TROIA have to use tables. The table used must contain two columns with predefined column names LOCALNAME and VALUE. LOCALNAME column must contain the same the element names (varInt,varFloat,varString) used inside the complex type(inputComplexType). Consider the code below :
OBJECT:
STRING WSDLADDR,
STRING OPERATION,
TABLE QTAB;
CLEAR ALL QTAB;
/* columns must have these names
APPEND COLUMN LOCALNAME,STRING,40 TO QTAB;
APPEND COLUMN VALUE,STRING,40 TO QTAB;
*
/
APPEND ROW TO QTAB;
MOVE 'varInt' TO QTAB_LOCALNAME;
MOVE '5' TO QTAB_VALUE;
APPEND ROW TO QTAB;
MOVE 'varString' TO QTAB_LOCALNAME;
MOVE 'ddd' TO QTAB_VALUE;
APPEND ROW TO QTAB;
MOVE 'varFloat' TO QTAB_LOCALNAME;
MOVE '3.0' TO QTAB_VALUE;
WSDLADDR = 'http://mssoapinterop.org/asmx/xsd/round4XSD.wsdl';
OPERATION = 'echoComplexType';
CALLWEBSERVICE WSDLADDR,OPERATION TO STRINGVAR3 WITH QTAB;
The envelope send whih can be seen by the trace:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<echoComplexType xmlns="http://soapinterop.org/">
<inputComplexType xmlns="http://soapinterop.org/">
<varInt xmlns="http://soapinterop.org/xsd">5</varInt>
<varString xmlns="http://soapinterop.org/xsd">ddd</varString>
<varFloat xmlns="http://soapinterop.org/xsd">3.0</varFloat>
</inputComplexType>
</echoComplexType>
</soapenv:Body>
</soapenv:Envelope>
The response from the service called, will also be stored as a soap envelope in STRINGVAR3:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<echoComplexTypeResponse xmlns="http://soapinterop.org/">
<return>
<varInt xmlns="http://soapinterop.org/xsd">5</varInt>
<varString xmlns="http://soapinterop.org/xsd">ddd</varString>
<varFloat xmlns="http://soapinterop.org/xsd">3</varFloat>
</return>
</echoComplexTypeResponse>
</soap:Body>
</soap:Envelope>
d. Finding Web Services
Up to now, this document dealt with how to produce and consume web services. Finding a web service throughout an XML registry is another significant feature used by web service developers and consumers. XML registries can be thought of as an electronic yellow pages where producers and consumers dynamically discover one another. TROIA supports querying XML registries with QUERYXMLREGISTRY function for a specific web service
OBJECT:
STRING UDDIREG,
STRING UDDIREGM,
STRING SERVICE,
STRING PHOST,
STRING PPORT;
UDDIREG = 'http://uddi.ibm.com/testregistry/inquiryapi';
UDDIREGM = 'http://test.uddi.microsoft.com/inquire';
SERVICE = '%WEATHER%';
PHOST = '192.168.0.196';
PPORT = '3128';
INTEGERVAR2 = QUERYXMLREGISTRY(UDDIREG,SERVICE,PHOST,PPORT);.
The code above queries the test registry provided by IBM (or Microsoft) for the services with the name ‘like(%) WEATHER’ . The last two parameters are optional for proxy host and port of the machine where CANIAS application server resides not the client. The integer returned shows the number of services that matches. This function not only returns the number of results found but the names and their access points as well in a table called SYSUDDIREGISTRY.
Developers of TROIA may consume a web service throughout this table as told in part c .
e. How to compile and deploy web services.
iasWebService is an rpc(remote process call) type service.
i. Compiling
The classes used are; iasWebServiceIF (interface) , iasWebServiceImpl (implementation), iasWebServiceHandler (a class used to store remote server stubs by the help of a static hashtable) and found in package ‘com.ias.web’. The interface file extends Remote class of java.
public interface iasWebServiceIF extends Remote {
.....
}
This interface will be used by the ‘wsdeploy’ tool to create rpc stubs and tie objects.
Compiling is done as usual with the classes explained above.
ii. Packaging and Deployment
Besides the classes, final deployment needs extra description files. These are ‘jaxrpc-ri.xml’ and ‘web.xml’ . The first file is a description file for iasWebService. Its content is:
<?xml version="1.0" encoding="UTF-8"?>
<webServices
xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/dd"
version="1.0"
targetNamespaceBase="urn:Foo"
typeNamespaceBase="urn:Foo"
urlPatternBase="/ws">
<endpoint
name="iasWebService"
displayName="Canias Web Service"
description="Canias Web service"
interface="com.ias.web.iasWebServiceIF"
implementation="com.ias.web.iasWebServiceImpl"/>
<endpointMapping
endpointName="iasWebService"
urlPattern="/iasWebService"/>
</webServices>
The second file is a standard web info file.
These two file must reside in a directory called ‘WEB-INF’. There is another directory called ‘classes’ is also needed. The necessary classeses ( classes compiled above and their dependants) must go under classes directory. Cause package info has to be preserved. The directory structure is shown below:
-- WEB-INF
-- jaxrpc-ri.xml
-- web.xml
-- classes
-- com
-- ias
-- globals
-- server
-- util
-- web
All com.ias packages and classes are not needed , all needed files are:
com.ias.globals:
iasEncryptDecrypt.class
iasRPCDocument.class
iasSeperators.class
XAction.class
Xparameter.class
com.ias.server:
iasServerManagerInterface.class
iasServerManagerRemoteObject_Stub.class
com.ias.util:
iasCompressor.class
com.ias.web:
iasWebServiceIF.class
iasWebServiceImpl.class
iasWebServiceHandler.class
After the directory structure is formed as explained above, ‘war’ package can be formed. Build an archive or use jar(jar cvf ..) command that will contain the classes and files above without loosing path infos into a war named ‘iasTempWebService’. This is a pre-deployment war so we named it as temporary file.
Now it is time for final deployment . ‘wsdeploy’ tool is needed in this stage. Usually it is shipped with jwsdp-1.3 ( Sun Java Web Services Development pack). A batch file ‘wsdeploy.bat‘ is found under ‘C:\jwsdp-1.3\jaxrpc\bin‘ .( It is assumed that jwsdp is founded under C:\ ). This tool creates stubs and ties and more important a ‘wsdl‘ file to describe our web service based on jaxrpc-ri.xml and others.Apply this tool to our intermediate war:
C:\jwsdp-1.3\jaxrpc\bin\wsdeploy.bat -o iasWebService.war iasTempWebService.war
This creates the final war ‘iasWebService.war’ . Copy this file to ‘webapps’ directory of your web server. Start your web server ( Tomcat for instance ) and test it. For example:
http://localhost:8080/iasWebService/iasWebService?WSDL
As it is seen these url matches with the content of our jaxrpc-ri.xml file. Every deployment needs web server to be restarted.
All the things that are told in ‘packaging and deployment’ section can also be made with ant tool. (Ant is sth like linux makefile )
f. What ‘s more .
i. Tables in ODBA
As discussed above two tables in CANIAS is needed. Their specification taken from CANIAS ODBA is below:
DROP TABLE IASWEBSERVICES;
CREATE TABLE IASWEBSERVICES (
CLIENT VARCHAR(2) NOT NULL,
SERVICENAME VARCHAR(20) NOT NULL,
SERVICECLASS VARCHAR(20) NOT NULL,
SERVICEFUNC VARCHAR(30) NOT NULL,
STEXT TEXT
) ;
CREATE UNIQUE INDEX IASTR_001 ON IASWEBSERVICES (CLIENT,SERVICENAME,SERVICECLASS,SERVICEFUNC);
DROP TABLE IASWSRIGHTS;
CREATE TABLE IASWSRIGHTS (
CLIENT VARCHAR(2) NOT NULL,
USERNAME VARCHAR(12) NOT NULL,
SERVICENAME VARCHAR(20) NOT NULL
) ;
CREATE UNIQUE INDEX IASTR_001 ON IASWSRIGHTS (CLIENT,USERNAME,SERVICENAME);
ii. Jars and packages
Download Java Web Services Developer Pack 1.3 from Sun. Also wsdl4j.jar,jaxrpc.jar,axis.jar,saaj.jar,commons-discovery.jar,commons-logging.jar, uddi4j.jar need to be added to project. These jars are found under C:\jwsdp-1.3\common\lib or JBuilderX\lib. Check for them.
One more extra jar must be added to C:\jwsdp-1.3\common\lib directory. That is soap.jar found in /resources/lib of pegasus project path. That file is used for ‘Base64Encoding’ functions. (Restart web server after copying it)
iii. Error tracing
Error logs are found under C:\jwsdp-1.3\logs\ launcher.server.log .