From 25d3d746cb7fdf809044a9a3d826fde9ea1bc599 Mon Sep 17 00:00:00 2001 From: erickson Date: Tue, 15 Jan 2008 23:24:31 +0000 Subject: [PATCH] I started adding some basic bootstrap options looking ahead to server-side python. This resulted in a small set of code cleanup including: move from camelCase to lower_under for method names move from global variables to class-level static variables move from global functions to class-level static functions git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1219 9efc2488-bf62-4759-914b-345cdb29e865 --- src/python/osrf/conf.py | 2 +- src/python/osrf/net.py | 43 ++++++++---- src/python/osrf/net_obj.py | 21 +++--- src/python/osrf/ses.py | 23 +++--- src/python/osrf/set.py | 8 +-- src/python/osrf/system.py | 140 +++++++++++++++++++++++-------------- src/python/srfsh.py | 21 +++--- 7 files changed, 151 insertions(+), 107 deletions(-) diff --git a/src/python/osrf/conf.py b/src/python/osrf/conf.py index 894f2d3..8bb00fa 100644 --- a/src/python/osrf/conf.py +++ b/src/python/osrf/conf.py @@ -30,7 +30,7 @@ class Config(object): self.data = {} #def parseConfig(self,file=None): - def parseConfig(self): + def parse_config(self): self.data = osrf.xml_obj.xml_file_to_object(self.file) Config.config = self diff --git a/src/python/osrf/net.py b/src/python/osrf/net.py index 3169738..e79b43b 100644 --- a/src/python/osrf/net.py +++ b/src/python/osrf/net.py @@ -38,6 +38,12 @@ def get_network_handle(): """ Returns the thread-specific network connection handle.""" return THREAD_SESSIONS.get(threading.currentThread().getName()) +def clear_network_handle(): + ''' Disconnects the thread-specific handle and discards it ''' + handle = THREAD_SESSIONS.get(threading.currentThread().getName()) + if handle: + handle.disconnect() + del THREAD_SESSIONS[threading.currentThread().getName()] class NetworkMessage(object): """Network message @@ -62,23 +68,32 @@ class NetworkMessage(object): else: self.sender = message.get_from().as_utf8() else: - if args.has_key('sender'): - self.sender = args['sender'] - if args.has_key('recipient'): - self.recipient = args['recipient'] - if args.has_key('body'): - self.body = args['body'] - if args.has_key('thread'): - self.thread = args['thread'] + self.sender = args.get('sender') + self.recipient = args.get('recipient') + self.body = args.get('body') + self.thread = args.get('thread') + self.router_command = args.get('router_command') + + def make_xmpp_msg(self): + ''' Creates a pyxmpp.message.Message and adds custom attributes ''' + + msg = Message(None, None, self.recipient, None, None, None, \ + self.body, self.thread) + if self.router_command: + msg.xmlnode.newProp('router_command', self.router_command) + return msg + + def to_xml(self): + ''' Turns this message into XML ''' + return self.make_xmpp_msg().serialize() + class Network(JabberClient): def __init__(self, **args): self.isconnected = False # Create a unique jabber resource - resource = 'python' - if args.has_key('resource'): - resource = args['resource'] + resource = args.get('resource') or 'python_client' resource += '_' + gethostname() + ':' + str(os.getpid()) + '_' + \ threading.currentThread().getName().lower() self.jid = JID(args['username'], args['host'], resource) @@ -115,10 +130,8 @@ class Network(JabberClient): def send(self, message): """Sends the provided network message.""" - osrf.log.log_internal("jabber sending to %s: %s" % \ - (message.recipient, message.body)) - msg = Message(None, None, message.recipient, None, None, None, \ - message.body, message.thread) + osrf.log.log_internal("jabber sending to %s: %s" % (message.recipient, message.body)) + msg = message.make_xmpp_msg() self.stream.send(msg) def message_received(self, stanza): diff --git a/src/python/osrf/net_obj.py b/src/python/osrf/net_obj.py index ce1e798..b71ee69 100644 --- a/src/python/osrf/net_obj.py +++ b/src/python/osrf/net_obj.py @@ -7,8 +7,6 @@ from xml.sax import saxutils # Define the global network-class registry # ----------------------------------------------------------- -# Global object registry -OBJECT_REGISTRY = {} class NetworkRegistry(object): ''' Network-serializable objects must be registered. The class @@ -16,19 +14,18 @@ class NetworkRegistry(object): of field names (keys). ''' + # Global object registry + registry = {} + def __init__(self, hint, keys, protocol): - global OBJECT_REGISTRY self.hint = hint self.keys = keys self.protocol = protocol - OBJECT_REGISTRY[hint] = self + NetworkRegistry.registry[hint] = self + @staticmethod def get_registry(hint): - global OBJECT_REGISTRY - return OBJECT_REGISTRY.get(hint) - - get_registry = staticmethod(get_registry) - + return NetworkRegistry.registry.get(hint) # ----------------------------------------------------------- # Define the base class for all network-serializable objects @@ -74,11 +71,9 @@ class NetworkObject(object): def get_field(self, field): return self._data.get(field) - def get_registry(cls): + def get_registry(self): ''' Returns the registry object for this registered class ''' - return cls.registry - get_registry = classmethod(get_registry) - + return self.__class__.registry def new_object_from_hint(hint): ''' Given a hint, this will create a new object of that diff --git a/src/python/osrf/ses.py b/src/python/osrf/ses.py index fa4fe07..4e66f24 100644 --- a/src/python/osrf/ses.py +++ b/src/python/osrf/ses.py @@ -192,7 +192,7 @@ class ClientSession(Session): for the request associated with the message's ID.""" osrf.log.log_debug("pushing %s" % message.payload()) try: - self.find_request(message.threadTrace()).pushResponse(message.payload()) + self.find_request(message.threadTrace()).push_response(message.payload()) except Exception, e: osrf.log.log_warn("pushing respond to non-existent request %s : %s" % (message.threadTrace(), e)) @@ -204,6 +204,17 @@ class ClientSession(Session): osrf.log.log_debug('find_request(): non-existent request %s' % str(rid)) return None + @staticmethod + def atomic_request(service, method, *args): + ses = ClientSession(service) + req = ses.request2(method, list(args)) + resp = req.recv() + data = resp.content() + req.cleanup() + ses.cleanup() + return data + + class Request(object): @@ -286,7 +297,7 @@ class Request(object): return None - def pushResponse(self, content): + def push_response(self, content): """Pushes a method response onto this requests response queue.""" self.queue.append(content) @@ -306,14 +317,6 @@ class ServerSession(Session): pass -def AtomicRequest(service, method, *args): - ses = ClientSession(service) - req = ses.request2(method, list(args)) - resp = req.recv() - data = resp.content() - req.cleanup() - ses.cleanup() - return data diff --git a/src/python/osrf/set.py b/src/python/osrf/set.py index 0a243b4..5c7d30b 100644 --- a/src/python/osrf/set.py +++ b/src/python/osrf/set.py @@ -14,8 +14,7 @@ # ----------------------------------------------------------------------- from osrf.const import OSRF_APP_SETTINGS, OSRF_METHOD_GET_HOST_CONFIG -import osrf.ex -import osrf.net_obj +import osrf.ex, osrf.net_obj, osrf.ses # global settings config object __config = None @@ -31,10 +30,7 @@ def get(path, idx=0): def load(hostname): global __config - from osrf.system import connect - from osrf.ses import ClientSession - - ses = ClientSession(OSRF_APP_SETTINGS) + ses = osrf.ses.ClientSession(OSRF_APP_SETTINGS) req = ses.request(OSRF_METHOD_GET_HOST_CONFIG, hostname) resp = req.recv(timeout=30) __config = resp.content() diff --git a/src/python/osrf/system.py b/src/python/osrf/system.py index f206205..9986d0d 100644 --- a/src/python/osrf/system.py +++ b/src/python/osrf/system.py @@ -13,59 +13,95 @@ # GNU General Public License for more details. # ----------------------------------------------------------------------- -from osrf.conf import Config, get, get_no_ex +import osrf.conf from osrf.net import Network, set_network_handle, get_network_handle import osrf.stack, osrf.log, osrf.set, osrf.cache -import sys - - -def connect(configFile, configContext, init_cache=False): - """ Connects to the opensrf network - @param configFile The OpenSRF config - @param configContext The path to the configuration element in the XML config. - e.g. 'config.opensrf' - @param init_cache If true, connect to the cache servers - """ - - if get_network_handle(): - ''' This thread already has a handle ''' - return - - # parse the config file - configParser = Config(configFile, configContext) - configParser.parseConfig() - - # set up logging - osrf.log.initialize( - osrf.conf.get('loglevel'), - osrf.conf.get_no_ex('syslog'), - osrf.conf.get_no_ex('logfile')) - - # connect to the opensrf network - network = Network( - host = osrf.conf.get('domains.domain'), - port = osrf.conf.get('port'), - username = osrf.conf.get('username'), - password = osrf.conf.get('passwd')) - - network.set_receive_callback(osrf.stack.push) - osrf.net.set_network_handle(network) - network.connect() - - # load the domain-wide settings file - osrf.set.load(osrf.conf.get('domains.domain')) - - if init_cache: - connect_cache() - - -def connect_cache(): - ''' Initializes the cache connections ''' - cache_servers = osrf.set.get('cache.global.servers.server') - if cache_servers: - if not isinstance(cache_servers, list): - cache_servers = [cache_servers] - if not osrf.cache.CacheClient.get_client(): - osrf.cache.CacheClient.connect(cache_servers) +import sys, os + +class System(object): + + config_file = None + config_context = None + + @staticmethod + def net_connect(**kwargs): + if get_network_handle(): + ''' This thread already has a handle ''' + return + + config_file = kwargs.get('config_file') or System.config_file + config_context = kwargs.get('config_context') or System.config_context + + # store the last config file info for later + System.config_file = config_file + System.config_context = config_context + + # parse the config file + config_parser = osrf.conf.Config(config_file, config_context) + config_parser.parse_config() + + # set up logging + osrf.log.initialize( + osrf.conf.get('loglevel'), + osrf.conf.get_no_ex('syslog'), + osrf.conf.get_no_ex('logfile')) + + # connect to the opensrf network + network = Network( + host = osrf.conf.get('domains.domain'), + port = osrf.conf.get('port'), + username = osrf.conf.get('username'), + password = osrf.conf.get('passwd'), + resource = kwargs.get('resource')) + + network.set_receive_callback(osrf.stack.push) + osrf.net.set_network_handle(network) + network.connect() + + return network + + + @staticmethod + def connect(**kwargs): + """ Connects to the opensrf network + Options: + config_file + config_context + connect_cache + resource + """ + + network = System.net_connect(**kwargs) + + # load the domain-wide settings file + osrf.set.load(osrf.conf.get('domains.domain')) + + if kwargs.get('connect_cache'): + System.connect_cache() + + return network + + + @staticmethod + def connect_cache(): + ''' Initializes the cache connections ''' + cache_servers = osrf.set.get('cache.global.servers.server') + if cache_servers: + if not isinstance(cache_servers, list): + cache_servers = [cache_servers] + if not osrf.cache.CacheClient.get_client(): + osrf.cache.CacheClient.connect(cache_servers) + + @staticmethod + def daemonize(): + pid = os.fork() + if pid == 0: + os.chdir('/') + os.setsid() + sys.stdin.close() + sys.stdout.close() + sys.stderr.close() + else: + os._exit(0) diff --git a/src/python/srfsh.py b/src/python/srfsh.py index c1daa5e..82daee2 100755 --- a/src/python/srfsh.py +++ b/src/python/srfsh.py @@ -223,7 +223,7 @@ def setup_readline(): def do_connect(): file = os.path.join(get_var('HOME'), ".srfsh.xml") print_green("Connecting to opensrf...") - osrf.system.connect(file, 'srfsh') + osrf.system.System.connect(config_file=file, config_context='srfsh') print_red('OK\n') def load_plugins(): @@ -247,7 +247,7 @@ def load_plugins(): print_green("Loading module %s..." % name) try: - string = 'from %s import %s\n%s()' % (name, init, init) + string = 'import %s\n%s.%s()' % (name, name, init) exec(string) print_red('OK\n') @@ -266,10 +266,7 @@ def set_var(key, val): os.environ[key] = val def get_var(key): - try: - return os.environ[key] - except: - return '' + return os.environ.get(key, '') def __get_locale(): """ @@ -289,10 +286,14 @@ def __get_locale(): """ env_locale = get_var('SRFSH_LOCALE') - pattern = re.compile(r'^\s*([a-z]+)[^a-zA-Z]([A-Z]+)').search(env_locale) - lang = pattern.group(1) - region = pattern.group(2) - locale = "%s-%s" % (lang, region) + if env_locale: + pattern = re.compile(r'^\s*([a-z]+)[^a-zA-Z]([A-Z]+)').search(env_locale) + lang = pattern.group(1) + region = pattern.group(2) + locale = "%s-%s" % (lang, region) + else: + locale = 'en-US' + return locale def print_green(string): -- 2.43.2