Question

I have problem with solution that was working very good and suddenly it stopped to do so. I wrote server/client scripts and modules to make a SOAP connection type for my application. Here is my server code :

import os
import rsglobal
import signal
import soaplib
from soaplib.core.service import rpc, DefinitionBase, soap
from soaplib.core.model.primitive import String, Integer
from soaplib.core.server import wsgi
from soaplib.core.model.clazz import Array

try:
    import psycopg
except:
    import psycopg2 as psycopg

import rssql

LogFile = "serwer_soap.log"


#-##############################################################################
#-- SOAP SERVER CLASS
#-##############################################################################

class AnakondaSOAPServer(DefinitionBase):

    #-##############################################################################
    #-- SOAP FUNCTIONS
    #-##############################################################################

    @soap(String,Integer,_returns=Array(String))
    def say_hello(self,name,times):
        results = []
        for i in range(0,times):
            results.append('Hello, %s'%name)
        return results

    @soap(String,String,_returns=String)
    def ConnectToBase(self,name,passwd):
        global PolSQL
        try:
            stat = 'OK'
            dane=[]
            PolSQL=rssql.RSSQL()

            if PolSQL.ConnectToSQL(name,passwd,'127.0.0.1',5432,'','databasename')==1:
                stat = u'Connection Error'

            SQL='SELECT * FROM table1;'
            stat,dane,dump,dump=PolSQL.Execute(SQL,3)
        except Exception,e:
            return u'Connection Error '+str(e)

        return stat+' '+str(dane)

    @soap(_returns=String)
    def GiveData(self):
        global PolSQL
        try:
            stat = 'OK'
            dane=[]
            SQL='SELECT * FROM table1;'
            stat,dane,dump,dump=PolSQL.Execute(SQL,3)
        except Exception,e:
            return u'Data getting error '+str(e)

        return stat+' '+str(dane)

    #------------------------------------------
    # ADMINISTRATIVE FUNCTIONS
    #------------------------------------------

    def SetDefaultData(self):
        self._oldHupHandler = signal.SIG_DFL
        self._oldAlarmHandler = signal.SIG_DFL
        self._oldTermHandler = signal.SIG_DFL
        self._childProcess = None
        self.PolSQL = None

#-------------------------------------------------------------------------------

    def _OnSIGALRM(self, sig, frame):
        pass

#-------------------------------------------------------------------------------

    def _OnSIGHUP(self, sig, frame):
        if self._childProcess:
            os.kill(self._childProcess, signal.SIGHUP)
        else:
            pass

#-------------------------------------------------------------------------------

    def _OnSIGTERM(self, sig, frame):
        pass

#-------------------------------------------------------------------------------

    def _exit(self, status):
        if self.PolSQL:
            self.PolSQL.DisconnectSQL()
        if status:
            rsglobal.Log(u"SOAP - finishing : "+str(status), 1)
        os._exit(status)

#-------------------------------------------------------------------------------

    def StartSOAPServer(self, dbspec,HostSOAP,PortSOAP):
        import os

        self.dbspec = dbspec
        childPID = os.fork()
        if childPID:
            self._childProcess = childPID
            return childPID
        else:
            try:
                signal.signal(signal.SIGUSR1, signal.SIG_DFL)
                signal.signal(signal.SIGCHLD, signal.SIG_DFL)
                if LogFile:
                    rsglobal.LogFile = LogFile

                self._oldHupHandler = signal.signal(signal.SIGHUP, lambda x, y: self._OnSIGHUP(x, y))
                self._oldAlarmHandler = signal.signal(signal.SIGALRM, lambda x, y: self._OnSIGALRM(x, y))
                self._oldTermHandler = signal.signal(signal.SIGTERM, lambda x, y: self._OnSIGTERM(x, y))
                self.PolSQL = SQLConnect(self.dbspec)

                # running SOAP server
                from wsgiref.simple_server import make_server
                ServiceSoap = soaplib.core.Application([AnakondaSOAPServer],'AnakSOAP',name='AnakSOAP')
                WSGI = wsgi.Application(ServiceSoap)
                Serwer = make_server(HostSOAP, int(PortSOAP), WSGI)
                Serwer.serve_forever()

            except Exception, exc:
                rsglobal.ZapiszDoLogow(u"Server SOAP Error : "+str(exc), 2)
                self._exit(1)

#-------------------------------------------------------------------------------

    def StopSOAPServer(self):
        if self._childProcess:
            os.kill(self._childProcess, signal.SIGTERM)

#-##################################################################


#-### - This is main SOAP server object used in other modules
SerwerSOAP = AnakondaSOAPServer()
SerwerSOAP.SetDefaultData()

#-##############################################################################
#-## ADDITIONAL FUNCTIONS
#-##############################################################################

def SQLConnect(dbspec):
    # creates connection to database

    PolSQL = rssql.RSSQL()
    dbuser, dbpass, dbhost, dbport, dbase = dbspec
    if PolSQL.PolaczZSQL(dbuser, dbpass, dbhost, dbport, None, Baza=dbase):
        return False
    else:
        return PolSQL

My client code (which just tests server) is like this :

from suds.client import Client

hello_client = Client('http://128.1.2.3:1234/AnakondaSOAPServer?wsdl')

hello_client.options.cache.clear()

result = hello_client.service.ConnectToBase("username", "password")
print 'Result1',result
result = hello_client.service.GiveData()
print 'Result2',result

Earlier in my main application i use function StartSOAPServer with proper parameters and it's waiting for connections. I can see it with netstat on good adress and port.

After running client script i get :

Traceback (most recent call last):
  File "./testsoapclient.py", line 8, in <module>
    hello_client = Client('http://128.1.2.3:1234/AnakondaSOAPServer?wsdl')
  File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/client.py", line 112, in __init__
    self.wsdl = reader.open(url)
  File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/reader.py", line 152, in open
    d = self.fn(url, self.options)
  File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/wsdl.py", line 158, in __init__
    self.resolve()
  File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/wsdl.py", line 207, in resolve
    c.resolve(self)
  File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/wsdl.py", line 494, in resolve
    raise Exception("msg '%s', not-found" % op.input)
Exception: msg 's0:ConnectToBase', not-found

Earlier i had problem with visibility of functions after creating a SOAP connection. Solution was to clear a cache. Now i can't even create it. I use python 2.6, and lately my main app was transfered from 2.4 to 2.6. It's the only difference i can think of.

I tried manipulate with soaplib.core.Application definition, but it didn't work.

Please help :)

Was it helpful?

Solution

I managed to overcome the problems and it's working again. First thing that repairs situation is splitting server into 2 classes - one to create object and run SOAPServer and second - SOAPServer which contains only definitions of functions.

Even after doing this changes i had bad results. I found out, that damaged structure of server definition hides in /tmp/suds directory (and that is why it was working while having damaged code before). Deleting this files allowed to refresh this structure and all scripts started to work again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top