Wednesday, April 23, 2008

GroovyWS and SOAP-Lite

Was trying out GroovyWS when it struck me that won't it be great if I could have Grooovy exposing the WS while SOAP-Lite would be used as a client. Now I've been experimenting with SOAP-Lite on the server side as well, but it is not my favourite. So to kick start the whole thing I started with Greeting webservice. Groovy code for the WS went as follows

---------- GreetService.groovy --------------------
public class GreetService {
String hi(String s) {
println s;
return "hi " + s;
}
String bye(String s) {
println s;
return "bye " + s;
}
}
---------------------------------------------------
---------- GreetWS.groovy -------------------------
import groovyx.net.ws.WSServer

def server = new WSServer()

server.setNode("GreetService", "http://localhost:6980/GreetService")
---------------------------------------------------

Once the server was running I got the perl client ready

---------- GreetClient.pl -------------------------
use SOAP::Lite;

my $serviceNs = 'http://DefaultNamespace';
my $serviceUrl = 'http://localhost:6980/GreetService';
my $soap = SOAP::Lite->uri($serviceNs)->proxy($serviceUrl);
print $soap->hi("atif")->result . "\n";
---------------------------------------------------

Everything should have worked but as usual it is never this easy. On running the client I got the following out

hi null

and on the server the output was

null

so somehow the string "atif" never got transmitted. Setting the debug option on

use SOAP::Lite +trace => 'debug';

output all the SOAP communication on the console. It became obvious that SOAP-Lite was encoding the string

<hi xmlns="http://DefaultNamespace"><c-gensym3 xsi:type="xsd:string">atif</c-gensym3></hi>

but somehow GroovyWS is not picking it up. Extracting the wsdl by browsing to http://localhost:6980/GreetService?wsdl indicated that the WS was expecting the string in variable named 'arg0'.

<xsd:complexType name="hi">
<xsd:sequence>
<xsd:element minOccurs="0" name="arg0" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>

The implementation of the GreetClient.pl does not use the wsdl, so I made the changes to make it

---------- GreetClient2.pl -------------------------
use SOAP::Lite;

my $serviceUrl = 'http://localhost:6980/GreetService?wsdl';
my $soap = SOAP::Lite->service($serviceUrl);
print $soap->hi("atif") . "\n";
----------------------------------------------------

executing the new client resulted in an error message

<faultstring>"http://schemas.xmlsoap.org/wsdl/soap/", the namespace on the "Envelope" element, is not a valid SOAP version.</faultstring>

as SOAP-Lite has limited support for WSDL 1.1. To solve this problem I ended up doing some searching and stumbling upon Complex SOAP::Lite requests - my rules for SOAP::Sanity!. Using the guide I made a new client

---------- GreetClient3.pl -------------------------
use SOAP::Lite;

my $serviceNs = 'http://DefaultNamespace';
my $serviceUrl = 'http://localhost:6980/GreetService';
my $soap = SOAP::Lite->uri($serviceNs)->proxy($serviceUrl);
my $data = SOAP::Data->name("arg0" => 'atif');
print $soap->hi($data)->result ."\n";
----------------------------------------------------

ATLAST!!! I got the output I expected.

hi atif

1 comment:

SoaMoaFan said...

Hi Atif,
if you should use groovyWS, I can recommend SoaMoa onn http://soamoa.org