Web Services Versioning using WSO2 WSAS and WSO2 ESB
- Davanum Srinivas
- - WSO2
Let us review what we know already. Axis 1.x based Web services are
primarily of rpc/encoded style, as that was the default option. Axis2 used
document/literal style as the default. So the SOAP requests that are sent by
the two sets of clients are very different from each other. So the first
issue is to figure out how to re-use the Axis 1.x classes and the wsdd
descriptor (migration). The second issue is how we can support legacy
(rpc/encoded) and modern (doc/lit) clients at the same time (versioning).
Thankfully, WSO2 WSAS and WSO2 ESB make it easy both for migration and for
versioning.
Sample Service and Deployment Descriptors
Let us take a quick look at the sample service and classes that we will
work with in this article. MyService is the service that needs to be
deployed:
package org.wso2.samples; public class MyService { public Employee[] getEmployees(){ return new Employee[]{ new Employee("Sanjiva","Weerawarana",1), new Employee("Paul","Fremantle",2) }; } }
and here's the Employee class:
package org.wso2.samples; public class Employee { public String firstName = null; public String lastName = null; public int id = 0; public Employee() { } public Employee(String firstName, String lastName, int id){ this.firstName = firstName; this.lastName = lastName; this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getID() { return id; } public void setID(int id) { this.id = id; } }
We can deploy this service in Axis 1.x using the following snippet in the
server-config.wsdd:
<service name="MyOldService" provider="java:RPC" style="rpc" use="encoded"> <parameter name="wsdlTargetNamespace" value="https://samples.wso2.org"/> <parameter name="wsdlServiceElement" value="MyServiceService"/> <parameter name="schemaUnqualified" value="https://samples.wso2.org"/> <parameter name="wsdlServicePort" value="MyService"/> <parameter name="className" value="org.wso2.samples.MyService"/> <parameter name="wsdlPortType" value="MyService"/> <parameter name="typeMappingVersion" value="1.2"/> <operation name="getEmployees" qname="operNS:getEmployees" xmlns:operNS="https://samples.wso2.org" returnQName="getEmployeesReturn" returnType="rtns:ArrayOfEmployee" xmlns:rtns="https://samples.wso2.org" returnItemType="tns2:Employee" xmlns:tns2="https://samples.wso2.org"> </operation> <parameter name="allowedMethods" value="getEmployees"/> <typeMapping xmlns:ns="https://samples.wso2.org" qname="ns:Employee" type="java:org.wso2.samples.Employee" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"/> <arrayMapping xmlns:ns="https://samples.wso2.org" qname="ns:ArrayOfEmployee" type="java:org.wso2.samples.Employee[]" innerType="cmp-ns:Employee" xmlns:cmp-ns="https://samples.wso2.org" encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"/> </service>
And the following services.xml in Axis2:
<service name="MyService"> <description> My Service class deployed on Axis2 </description> <parameter name="ServiceClass">org.wso2.samples.MyService</parameter> <operation name="getEmployees"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> </service>
Installing Services on WSO2 WSAS
- Download WSO2 WSAS 2.0 from
href="https://dist.wso2.org/products/wsas/java/2.0/">https://dist.wso2.org/products/wsas/java/2.0/
and unzip to say C:\wso2wsas-2.0 - The WSO2 WSAS server by default uses ports 9762 and 9443. Unfortunately
WSO2 ESB uses 8080, 8443 and 9443. So let's switch the WSAS ports to
avoid clashing with ESB - Edit c:\wso2wsas-2.0\conf\server.xml and add the following snippet:
<Ports> <HTTP>7070</HTTP> <HTTPS>7443</HTTPS> </Ports>
- Edit c:\wso2wsas-2.0\conf\axis2.xml and replace the ports (9762 with
7070 and 9443 with 7443) - Make sure JDK1.5's java.exe is on the command line, cd to
c:\wso2wsas-2.0\bin and run "wso2wsas run". You will see an output
similar to the one below:Starting WSO2 Web Services Application Server v2.0 (in JDK 1.5) Using WSO2WSAS_HOME: C:\WSO2WS~1.0\bin\.. Using JAVA_HOME: C:\JDK15 INFO [2007-09-05 23:23:27,552] Using WSO2 WSAS Home = C:\WSO2WS~1.0\bin\.. INFO [2007-09-05 23:23:27,585] Using Server Info Class = org.wso2.wsas.serverinfo.EmbeddedTomcatServerInfo INFO [2007-09-05 23:23:33,321] Deploying module: addressing-1.25 INFO [2007-09-05 23:23:33,374] Deploying module: rahas-1.25 INFO [2007-09-05 23:23:33,641] Deploying module: rampart-1.25 INFO [2007-09-05 23:23:33,666] Deploying module: wso2mex-2.0 INFO [2007-09-05 23:23:34,068] Deploying module: sandesha2-2.0 INFO [2007-09-05 23:23:34,085] Deploying module: wso2statistics-2.0 INFO [2007-09-05 23:23:34,126] Deploying module: wso2throttle-2.0 INFO [2007-09-05 23:23:34,148] Deploying module: wso2tracer-2.0 INFO [2007-09-05 23:23:34,152] Deploying module: wso2wsas-admin-2.0 INFO [2007-09-05 23:23:34,174] Deploying module: wso2xfer-2.0 INFO [2007-09-05 23:23:34,527] Deploying module: addressing-1.25 INFO [2007-09-05 23:23:34,540] Deploying module: wso2mex-2.0 INFO [2007-09-05 23:23:43,484] Deploying Web service: echo.aar INFO [2007-09-05 23:23:44,122] Deploying Web service: version.aar INFO [2007-09-05 23:23:44,241] Deploying Web service: wso2codegen.aar INFO [2007-09-05 23:23:44,580] Deploying Web service: wso2wsas-administration.aar INFO [2007-09-05 23:23:44,865] Deploying Web service: wso2wsas-sts.aar INFO [2007-09-05 23:23:45,128] Deploying Web service: xkms.aar INFO [2007-09-05 23:23:46,719] Command listener starting on port ----> 6666 INFO [2007-09-05 23:23:46,719] Using Repository C:\WSO2WS~1.0\bin\../repository/ INFO [2007-09-05 23:23:46,720] INFO [2007-09-05 23:23:46,720] Listening for HTTP on ----> 7070 INFO [2007-09-05 23:23:46,720] Listening for HTTPS on ----> 7443 INFO [2007-09-05 23:23:46,720] INFO [2007-09-05 23:23:46,720] WSO2 WSAS started in 22131 ms
- Point your browser to https://localhost:7443/ Login using admin/admin
as the user ID and password and click on the services link. - To upload the Axis2 service, click on "Upload Service Artifact
(.aar,.jar,.zip,.dbs)" and upload myservice-axis2.aar (see Downloads
below) - To upload the Axis1 service, click on "Upload Axis1 Service (.wsdd)"
and upload myservice-axis1.jar and server-config.wsdd (see Downloads
below) - After a few seconds, you will see both the Axis1 and Axis2 services
show up on the console:
Install WSO2 ESB and Set up a Mediation for Versioning
- Download WSO2 ESB 1.0 from
href="https://dist.wso2.org/products/esb/java/1.0/">https://dist.wso2.org/products/esb/java/1.0/
and unzip to say C:\wso2esb-1.0 - Make sure JDK1.5's java.exe is on the command line, cd to
c:\wso2esb-1.0\bin and run "wso2-esb run". You will see an output similar
to the one below:Using Bouncy castle JAR for Java 1.5 "Starting WSO2 Enterprise Service Bus ..." Using ESB_HOME: E:\WSO2ES~1.0\bin\.. Using JAVA_HOME: C:\JDK15 Using SYNAPSE_XML: -Dsynapse.xml="E:\WSO2ES~1.0\bin\..\conf\synapse.xml" INFO [06 Sep 00:38:40] ServiceBusConfiguration - Service Bus Configuration loaded from : conf/server.xml INFO [06 Sep 00:38:40] ServiceBus - Using Repository E:\WSO2ES~1.0\.\repository INFO [06 Sep 00:38:41] ServiceBusManager - Database server started on localhost over port 1528 INFO [06 Sep 00:38:42] ModuleDeployer - Deploying module: addressing INFO [06 Sep 00:38:42] ModuleDeployer - Deploying module: authentication INFO [06 Sep 00:38:42] ModuleDeployer - Deploying module: rampart INFO [06 Sep 00:38:42] ModuleDeployer - Deploying module: sandesha2 INFO [06 Sep 00:38:42] ModuleDeployer - Deploying module: synapse-1.0 INFO [06 Sep 00:38:42] ModuleDeployer - Deploying module: wso2statistics INFO [06 Sep 00:38:42] SynapseModule - Initializing the Synapse configuration ... INFO [06 Sep 00:38:42] XMLConfigurationBuilder - Generating the Synapse configuration model by parsing the XML configuration INFO [06 Sep 00:38:42] SynapseConfigurationBuilder - Loaded Synapse configuration from : E:\WSO2ES~1.0\bin\..\conf\synapse.xml INFO [06 Sep 00:38:42] SynapseModule - Deploying the Synapse service.. INFO [06 Sep 00:38:42] SynapseModule - Initializing Sandesha 2... INFO [06 Sep 00:38:42] SynapseModule - Deploying Proxy services... INFO [06 Sep 00:38:42] SynapseModule - Synapse initialized successfully...! INFO [06 Sep 00:38:43] HttpCoreNIOSender - HTTPS Sender starting INFO [06 Sep 00:38:43] HttpCoreNIOSender - HTTP Sender starting INFO [06 Sep 00:38:53] ServiceDeployer - Deploying Web service: ESBAdmin.aar INFO [06 Sep 00:38:54] HttpCoreNIOListener - HTTPS Listener starting on port : 8443 INFO [06 Sep 00:38:54] HttpCoreNIOListener - HTTP Listener starting on port : 8080 INFO [06 Sep 00:38:54] JettyServer - Console listener started on port 9443 over HTTPS. Connect to https://192.168.2.105:9443/ INFO [06 Sep 00:38:54] ServiceBus - WSO2 ESB started in 15004 ms
- Point your browser to https://localhost:9443/ Login using admin/admin
as the user ID and password, and click on the Configuration link - Copy the contents of esb-configuration.xml into the edit box, click
Update and then click Save. - Now if you click on Proxy Services, Endpoints or Sequences, you can
grapically view the information that was picked up from the
esb-configuration.xml - In particular, https://localhost:8080/soap/MyService is the new endpoint
that redirects the SOAP requests to
https://localhost:7070/services/MyService for newer doc/lit clients and to
https://localhost:7070/services/MyOldService for old rpc/encoded style
clients. - When you click on Sequences, and look at "inSequence", you will see
that we use an xpath expression //*[local-name()='getEmployees']
to decide which endpoint needs to be invoked. Here's the corresponding
configuration snippet:<syn:sequence name="inSequence"> <syn:filter xpath="//*[local-name()='getEmployees']"> <syn:send> <syn:endpoint key="Axis1Service"/> </syn:send> <syn:drop/> </syn:filter> <syn:send> <syn:endpoint key="Axis2Service"/> </syn:send> </syn:sequence>
Basically inside the SOAP body, for rpc/encoded requests, there is an
additional element named "getEmployees". So we look for that to identify
that it is an rpc/encoded request. - If you browse through the esb-configuration.xml, you will see that we
used an inline WSDL for the axis1 service and a URL for the axis2
service. This is because, when we deploy an Axis1 service, the WSDL picks
up the https:// endpoint. So we had to copy the WSDL and make the change
to refer to https:// endpoint.
Testing the New Endpoint
- You can use a tool like SOAPUI or XMLSPY to test the actual Web
services deployed on WSO2 WSAS first, the wsdl's for those are
https://localhost:7070/services/MyOldService?wsdl and
https://localhost:7070/services/MyService?wsdl - For example, when you send the following SOAP request to
https://localhost:7070/services/MyOldService<SOAP-ENV:Envelope xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="https://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <m:getEmployees xmlns:m="https://samples.wso2.org" SOAP-ENV:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"/> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
you will get the following:
<soapenv:Envelope xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema"> <soapenv:Body xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/"> <ns1:getEmployeesResponse xmlns:ns1="https://samples.wso2.org" soapenv:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/"> <getEmployeesReturn xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" soapenc:arrayType="ns1:Employee[2]" xsi:type="soapenc:Array"> <getEmployeesReturn href="#id0"/> <getEmployeesReturn href="#id1"/> </getEmployeesReturn> </ns1:getEmployeesResponse> <multiRef xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="https://samples.wso2.org" id="id0" soapenc:root="0" soapenv:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Employee"> <ID xsi:type="xsd:int">1</ID> <firstName xsi:type="xsd:string">Sanjiva</firstName> <lastName xsi:type="xsd:string">Weerawarana</lastName> <id xsi:type="xsd:int">1</id> </multiRef> <multiRef xmlns:ns3="https://samples.wso2.org" xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" id="id1" soapenc:root="0" soapenv:encodingStyle="https://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:Employee"> <ID xsi:type="xsd:int">2</ID> <firstName xsi:type="xsd:string">Paul</firstName> <lastName xsi:type="xsd:string">Fremantle</lastName> <id xsi:type="xsd:int">2</id> </multiRef> </soapenv:Body> </soapenv:Envelope>
- For example, when you send the following SOAP request to
https://localhost:7070/services/MyService<SOAP-ENV:Envelope xmlns:SOAP-ENV="https://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="https://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body/> </SOAP-ENV:Envelope>
you will get the following:
<soapenv:Envelope xmlns:soapenv="https://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns:getEmployeesResponse xmlns:ns="https://samples.wso2.org" xmlns:ax225="https://samples.wso2.org/xsd"> <ns:return type="org.wso2.samples.Employee"> <ax225:firstName>Sanjiva</ax225:firstName> <ax225:lastName>Weerawarana</ax225:lastName> </ns:return> <ns:return type="org.wso2.samples.Employee"> <ax225:firstName>Paul</ax225:firstName> <ax225:lastName>Fremantle</ax225:lastName> </ns:return> </ns:getEmployeesResponse> </soapenv:Body> </soapenv:Envelope>
- Finally, try sending both types of SOAP requests to
https://localhost:8080/soap/MyService and make sure you get the right
response back.
Applies To
1. WSO2 WSAS 2.0
2. WSO2 ESB 1.0
Downloads
1. myservice-axis1.jar and server-config.wsdd for deploying the
MyOldService - Axis1 service
2. myservice-axis2.aar for
deploying MyService - Axis2 service
3. esb-configuration.xml -
pre-built ESB Configuration