On Thu, Nov 5, 2009 at 6:28 PM, Hari Krishna Dara <haridara at gmail.com>
wrote:> I recently started trying R and SSOAP and was able to successfully try a
"hello
> world" service. I am now trying to get a more complicated interface to
work with
> SSOAP and so far failed miserably at that and so need any help I can
> get from here.
>
> The service I am attaching is a prototype for a full service that would
> take information to identify a data source and a query to run and
> return a tabular
> data (a sql query result or a dataframe in R).
>
> Note: If you are impatient to read the long email, you may skip to the
> description of
> "Third attempt"
>
> First attempt: I have a ServiceInfo type as part of the request, that has
two
> components, a clientID that is an int and a serviceInfoType that is an
enum. I
> was able to create the ServiceInfo class object and was able to make the
> function call, but I was getting an error in the toSOAP().
>
> ? ?> sinfo = c(clientId=1, serviceType='Engine')
> ? ?> class(sinfo) <- def at classes$`SOAP/DataService`$ServiceInfo
> ? ?> res = def at functions$simpleQuery(sinfo, 'select 1 as
One')
> ? ?Loading required package: bitops
> ? ?Error in toSOAP(argValues[[i]], methodCall, type = typedef,
> literal = .literal) :
> ? ? ?No code yet for the toSOAP method for any object and
> ClassDefinition pair with literal = FALSE
>
> Second attempt: I then flattened the ServiceInfo such that the clientId and
> sericeType are passed inline to bypass the above error. SSOAP went past
that but
> complained about a missing elType (seems to not like the enum).
>
> ? ?> res = def at functions$simpleQuery(1, 'Engine', 'select
1 as One')
> ? ?Error in toSOAPArray(obj, con, type = type, literal = literal, ...) :
> ? ? ?no slot of name "elType" for this object of class
> "RestrictedStringDefinition"
>
> Third attmept: To bypass the above error as well, I then changed
serviceType to
> string. SSOAP then actually made a successful call, and the webservice
returned
> a response. However, now SSOAP failed to deserialize it with the below
error
>
> ? ?> res = def at functions$simpleQuery(1, 'Engine', 'select
1 as One')
> ? ?Error in as(from, "QueryResultRow") :
> ? ? ?no method or default for coercing "XMLInternalElementNode"
to
> "QueryResultRow"
>
> I have since then created a standalone version of the service that only
takes
> the query (no clientId and serviceType) and attached the code. The service
is
> written in python using ZSI, and there is ZSI client code in the comments
that
> shows how to use it from a python client (which btw, works as expected).
The
> code doesn't actually execute the query, it simply fills in dummy data
into the
> result, so all that you need to try the sample is python 2.6 and ZSI
> (http://pywebsvcs.sourceforge.net/). The comment also has sample R client
code
> which I am paste below:
>
> ? ?library(SSOAP)
> ? ?dataService <-
>
processWSDL('C:/src/tmp/python/webserv/dataService/DataService.wsdl')
> ? ?def = genSOAPClientInterface(def = dataService, verbose = TRUE)
> ? ?res = def at functions$simpleQuery('select 1 as One')
>
> At this point, my priority is to get the deserialization of the response
> working, as I am able to workaround the first two issues in sending
request. I
> would really appreciate if anyone can help me in solving this problem.
>
> Here is some more information on getting the python sample to work.
> - Save the wsdl and py file in the same directory.
> - After installing python 2.6 and ZSI, run the below commands:
> ? ?$ wsdl2py --complexType --file DataService.wsdl
> ? ?$ wsdl2dispatch --file DataService.wsdl
> - Run the below command to start the service:
> ? ?$ python DataService.py
> - Start another python shell and run the below commands to see it in
action:
> ? ?$ python
> ? ?>>> import sys
> ? ?>>> from DataService_services import *
> ? ?>>> loc = DataServiceServiceLocator()
> ? ?>>> service = loc.getDataServicePortType(tracefile=sys.stdout)
> ? ?>>> req = DataServiceQueryRequest()
> ? ?>>> req.Query = "select 1 as One"
> ? ?>>> res = service.simpleQuery(req)
> ? ?>>> print "Field names: %s" % [field.StringValue for
field in
> ? ?... ? ?res.Result.ResultHeading.QueryFields]
> ? ?>>> print "Rows:"
> ? ?>>> for i in xrange(0, len(res.Result.ResultRows)):
> ? ?>>> ? ? print "Row %d: %s" % (i+1, [field.StringValue
or
> ? ?... ? ? field.LongValue or field.DoubleValue for field in
> ? ?... ? ? res.Result.ResultRows[i].QueryFields])
>
> Please let me know if you need any more information on the problem or
getting
> the python sample to work.
>
> Thank you,
> Hari
>
I have been trying some more variations. I also noticed that KEGG had
a working example that had a ComplexType involving arrays and so
reworked my schema to look simialar to that (that involves
soapenc:Array). Now my return type is directly an array (which
combines the header and rows) but this also didn't workout any better.
I then simplified further by removing the second level ComplexType,
ie., change QueryResultRow.queryFields to type "string" instead of a
ComplexType, and this got the call working. Ie., if I concatenate all
fields in a row as a single string, then SSOAP is able to deserialize
it. This of course is not what I want to do, so still looking for
help. I am attaching the new samples, one that works and the other
that doesn't (gives the below error):
Error in UseMethod("xmlValue") :
no applicable method for 'xmlValue' applied to an object of class
"NULL"
Is this a known limitation in SSOAP for handling ComplexTypes that are
more than 1 level deep? I am almost out of ideas and would soon look
into using JSON as an alternative, but that is not going to be my
preference.
Thank you,
Hari