[R] issues with SSOAP when wsdl has ComplexTypes

Hari Krishna Dara haridara at gmail.com
Fri Nov 6 03:28:35 CET 2009


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


More information about the R-help mailing list