質問

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 :)

役に立ちましたか?

解決

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top