00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 import random
00012 import string
00013 import time
00014 import types
00015 import threading
00016 import logging
00017
00018 from dimc import *
00019 from dimcpp import *
00020 from debug import *
00021
00022 _version = '1.3.4'
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 class PyDimRpcProxy (DimRpc):
00045 def __init__(self, funcs, rpcName='testRPC'):
00046 DimRpc.__init__(self, rpcName, 'C', 'C')
00047 self.lastValue = None
00048 self.funcs = {}
00049 self.name = rpcName
00050 if not hasattr(funcs, '__iter__'):
00051 funcs = [funcs]
00052 for f in funcs:
00053
00054 if hasattr(f, '__call__'):
00055 self.funcs[f.func_name] = f
00056 else:
00057 ERROR ('Object %s is not callable' %f)
00058 DEBUG(dir(f))
00059
00060 def convert(self, args):
00061 ret = ""
00062 if not hasattr(args, '__iter__'):
00063 args = (args,)
00064 for x in args:
00065 add = str(x)
00066 add = add.replace('/', '\/')
00067 add = add.replace('=', '\=')
00068 add = add.replace(',', '\,')
00069 ret += add + ','
00070 return ret[:-1]
00071
00072 def split(self, s, sep, exc='\\'):
00073 args = []
00074 poz = 0
00075 while s:
00076 poz = s.find(sep, poz)
00077 if poz == 0:
00078 s = s[1:]
00079 elif poz == -1:
00080 args.append(s)
00081 s = ""
00082 elif s[poz-1] != exc:
00083 args.append(s[:poz])
00084 s = s[poz+1:]
00085 poz = 0
00086 else:
00087 poz += 1
00088 if len(args) > 1 or len(args) == 0:
00089 return args
00090 else:
00091 return args[0]
00092
00093 def parse(self, s):
00094 pozArgs = []
00095 keyArgs = {}
00096 args = self.split(s, '/')
00097 if type(args) is str: args = (args,)
00098 DEBUG(args)
00099 for arg in args:
00100
00101 poz = arg.find('=')
00102 if poz > 0 and arg[poz-1] != '\\':
00103
00104 keyArgs[arg[:poz]] = self.split(arg[poz+1:], ',')
00105 else:
00106 pozArgs.append(self.split(arg, ','))
00107 return pozArgs, keyArgs
00108
00109 def rpcHandler(self):
00110 s = self.getString()
00111 DEBUG("Received: ", s)
00112
00113 if s.find('/') > -1:
00114 funcName = s[:s.find('/')]
00115 s = s[s.find('/'):]
00116 elif s:
00117
00118 funcName = s
00119 s = ""
00120 else:
00121 self.setData('ERROR: function %s is not registered' %s)
00122 return
00123 try:
00124 funcObj = self.funcs[funcName]
00125 except KeyError, e:
00126 ERROR(e)
00127 self.setData('status=FAIL/error=Could not find function '+str(e))
00128 return
00129
00130 pozArgs, keyArgs = self.parse(s)
00131
00132 ret = funcName + '/'
00133
00134 try:
00135 res = funcObj(*pozArgs, **keyArgs)
00136 except Exception, e:
00137
00138 print type(funcObj)
00139 ret += 'status=FAIL/error='+str(e)
00140 DEBUG('Returning exception message: %s' %ret)
00141 else:
00142 '''
00143 We have an result. Converting to a string and returning it.
00144 There can be two types of returned results: iterables and
00145 dictionaries. Both results can contain basic types or other
00146 iterables.
00147 Iterables: They will be converted in the equivalent of positional
00148 arguments for calling a function.
00149 Dictionaries: Will be converted in the equivalent of named
00150 arguments.
00151 '''
00152 if res[0] == 0:
00153 ret += 'status=ERROR/'
00154 try:
00155 ret = '%serror=%s/' %(ret, res[1])
00156 except:
00157 pass
00158 else:
00159 ret += 'status=SUCCESS/'
00160 named = False
00161 try:
00162 res = res[1]
00163 except:
00164 pass
00165 else:
00166 if isinstance(res, dict):
00167 for x in res:
00168 ret = "%s%s=%s/" %(ret,
00169 self.convert(x),
00170 self.convert(res[x])
00171 )
00172 elif hasattr(res, '__iter__'):
00173 for x in res:
00174 ret = "%s%s/" %(ret, self.convert(x))
00175 else:
00176 ret = "%s%s/" %(ret, self.convert(res))
00177
00178 ret += '\0'
00179
00180 DEBUG('Sending result: %s' %ret)
00181 self.setData(ret)
00182
00183
00184
00185
00186
00187
00188 class Dns:
00189 def __init__(self):
00190 self.dns_srv_sub = dim.Subscription(name = "DIS_DNS/SERVER_LIST",
00191 tag = self, schema = "S",
00192 handler = self.servers_update)
00193 self.servers = None
00194 def services_update(self, svcstr):
00195 self.services = []
00196 for s in string.split(svcstr[0], '\n'):
00197 if s == '': continue
00198 i = string.rfind(s, '|')
00199 j = string.rfind(s, '|', 0, i)
00200 print s, i, j
00201 if (i == len(s) - 1):
00202 type = "SVC"
00203 else:
00204 type = s[i + 1:(len(s))]
00205 self.services.append([ s[0:j], s[j+1:i], type])
00206 self.service_update = True
00207
00208 def servers_update(self, srv):
00209 self.servers = []; self.server_host = []
00210 for s in string.split(srv[0], '|'):
00211 [server, host ] = string.split(s, '@')
00212 self.servers.append(server)
00213 self.server_host.append([server, host])
00214
00215 def get_services(self, server):
00216 if (not server in self.servers): return None;
00217 self.service_update = False
00218 srv = dim.Subscription(name=server+"/SERVICE_LIST", schema = "S",
00219 handler = self.services_update)
00220 i = 0
00221 while (self.service_update == False and i < 50):
00222 i += 1
00223 time.sleep(0.1)
00224 return self.services
00225 def get_servers(self):
00226 while (self.servers == None):
00227 time.sleep(0.1)
00228 return self.servers
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 def dim_service(fn):
00239 def svc(tag):
00240
00241 rtn = fn()
00242
00243 if not rtn in (types.ListType, types.TupleType):
00244 rtn = (rtn,)
00245 return rtn
00246
00247 return svc
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 def dim_service_tag(fn):
00259 def svc(tag):
00260 rtn = fn(tag)
00261 if not rtn in (types.ListType, types.TupleType):
00262 rtn = (rtn,)
00263 return rtn
00264
00265 return svc
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 def dic_sync_info_service(name, description, timeout=None, default_value=None):
00289 executed = threading.Event()
00290 state = dict(value=None)
00291
00292 def create_callback(st):
00293 def _callback(*args):
00294 st['value'] = args
00295 executed.set()
00296
00297 return _callback
00298
00299 callback = create_callback(state)
00300 dim_timeout = 0
00301 tag = random.randint(0,100000)
00302 sid = dic_info_service(name, description, callback, ONCE_ONLY, dim_timeout, tag, default_value)
00303
00304 executed.wait(timeout)
00305
00306 dic_release_service(sid)
00307
00308 return state['value']
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 def dic_sync_cmnd_service(name, arguments, description, timeout=None):
00335 executed = threading.Event()
00336 state = dict(retcode=None)
00337
00338 def create_callback(st):
00339 def _callback(tag, retcode):
00340 state['retcode'] = retcode
00341 executed.set()
00342
00343 return _callback
00344
00345 callback = create_callback(state)
00346 tag = 0
00347 dic_cmnd_callback(name, arguments, description, callback, tag)
00348
00349 executed.wait(timeout)
00350
00351 return state['retcode']
00352
00353
00354 if __name__ == "__main__":
00355
00356 dns = Dns()
00357 print dns.get_servers()
00358 pass
00359
00360
00361