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
issues with SSOAP when wsdl has ComplexTypes
2 messages · Hari Krishna Dara
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