6
import SimpleXMLRPCServer,signal,sys,xmlrpclib
22
class ServiceEndPointCall(object):
23
def __init__(self,id,method):
26
def __call__(self,*args):
27
_res[self._id]=self._meth(*args)
30
class ServiceEndPoint(object):
31
def __init__(self, name, id):
37
self._meth[m]=s._method[m]
38
def __getattr__(self, name):
39
return ServiceEndPointCall(self._id, self._meth[name])
41
class Service(object):
42
_serviceEndPointID = 0
43
def __init__(self, name, audience=''):
47
self.exportedMethods=None
48
self._response_process=None
49
self._response_process_id=None
52
def joinGroup(self,name):
53
if not name in _group:
55
_group[name][self.__name]=self
57
def exportMethod(self, m):
59
self._method[m.__name__]=m
61
def serviceEndPoint(self,s):
62
if Service._serviceEndPointID >= 2**16:
63
Service._serviceEndPointID = 0
64
Service._serviceEndPointID += 1
65
return ServiceEndPoint(s, self._serviceEndPointID)
67
def conversationId(self):
70
def processResponse(self,s,id):
71
self._response_process, self._response_process_id = s, id
73
def processFailure(self,s,id):
76
def resumeResponse(self,s):
79
def cancelResponse(self,s):
82
def suspendResponse(self,s):
83
if self._response_process:
84
self._response_process(self._response_process_id,
85
_res[self._response_process_id])
86
self._response_process=None
87
self._response=s(self._response_process_id)
89
def abortResponse(self,error, description, origin, details):
91
if not tools.config['debug_mode']:
92
raise Exception("%s -- %s\n\n%s"%(origin,description,details))
96
def currentFailure(self,s):
99
class LocalService(Service):
100
def __init__(self, name):
105
setattr(self,m,s._method[m])
107
class ServiceUnavailable(Exception):
114
LOG_CRITICAL='critical'
117
from tools import config
120
if config['logfile']:
121
logf = config['logfile']
122
# test if the directories exist, else create them
124
if not os.path.exists(os.path.dirname(logf)):
125
os.makedirs(os.path.dirname(logf))
129
handler = logging.StreamHandler(fd)
132
sys.stderr.write("ERROR: couldn't open the logfile\n")
133
handler = logging.StreamHandler(sys.stdout)
136
sys.stderr.write("ERROR: couldn't create the logfile directory\n")
137
handler = logging.StreamHandler(sys.stdout)
139
handler = logging.StreamHandler(sys.stdout)
141
# create a format for log messages and dates
142
formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s', '%a, %d %b %Y %H:%M:%S')
144
# tell the handler to use this format
145
handler.setFormatter(formatter)
147
# add the handler to the root logger
148
logging.getLogger().addHandler(handler)
149
logging.getLogger().setLevel(logging.INFO)
152
class Logger(object):
153
def notifyChannel(self,name,level,msg):
154
log = logging.getLogger(name)
155
getattr(log,level)(msg)
161
def setAlarm(self, fn, dt, args=[], kwargs={}):
162
wait = dt - time.time()
164
self._logger.notifyChannel(
166
"Job scheduled in %s seconds for %s.%s" % (wait,
167
fn.im_class.__name__,
169
timer = threading.Timer(wait, fn, args, kwargs)
171
self._timers.append(timer)
172
for timer in self._timers[:]:
173
if not timer.isAlive():
174
self._timers.remove(timer)
177
for timer in cls._timers:
179
quit=classmethod(quit)
181
class RpcGateway(object):
182
def __init__(self, name):
185
class Dispatcher(object):
188
def monitor(self,signal):
193
class xmlrpc(object):
194
class RpcGateway(object):
195
def __init__(self, name):
198
class GenericXMLRPCRequestHandler:
199
def _dispatch(self, method, params):
202
n=self.path.split("/")[-1]
203
# print "TERP-CALLING:",n,method,params
206
s._service._response=None
208
res=s._service._response
210
# print "RESPONSE FOUND"
212
# print "TERP-RETURN :",r
215
print "Exception in call:"
217
traceback.print_exc(file=sys.stdout)
221
if tools.config['debug_mode']:
223
tb = sys.exc_info()[2]
225
raise xmlrpclib.Fault(1,s)
227
class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
231
class SecureXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SecureXMLRPCServer.SecureXMLRPCRequestHandler):
236
class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):
237
def server_bind(self):
238
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
239
SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
242
class SecureThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SecureXMLRPCServer.SecureXMLRPCServer):
243
def server_bind(self):
244
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
245
SecureXMLRPCServer.SecureXMLRPCServer.server_bind(self)
249
class HttpDaemon(object):
250
def __init__(self, interface,port, secure=False):
252
self.__interface=interface
253
if secure and HAS_SSL:
254
self.server = SecureThreadedXMLRPCServer((interface, port), SecureXMLRPCRequestHandler,0)
256
self.server = SimpleThreadedXMLRPCServer((interface, port), SimpleXMLRPCRequestHandler,0)
258
def attach(self,path,gw):
261
def handler(self,signum, frame):
262
self.server.socket.close()
263
self.server.socket.close()
265
# if tools.config['pidfile']:
266
# os.unlink(tools.config['pidfile'])
271
# if tools.config['pidfile']:
272
# fd=open(tools.config['pidfile'], 'w')
273
# pidtext="%d" % (os.getpid())
276
signal.signal(signal.SIGINT, self.handler)
277
signal.signal(signal.SIGTERM, self.handler)
278
self.server.register_introspection_functions()
280
self.server.serve_forever()
282
# If the server need to be run recursively
284
#signal.signal(signal.SIGALRM, self.my_handler)
287
# self.server.handle_request()
288
#signal.alarm(0) # Disable the alarm