1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-common.
#
# logilab-common is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option) any
# later version.
#
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
"""Python Remote Object utilities
Main functions available:
* `register_object` to expose arbitrary object through pyro using delegation
approach and register it in the nameserver.
* `ns_unregister` unregister an object identifier from the nameserver.
* `ns_get_proxy` get a pyro proxy from a nameserver object identifier.
"""
__docformat__ = "restructuredtext en"
import logging
import tempfile
from Pyro import core, naming, errors, util, config
_LOGGER = logging.getLogger('pyro')
_MARKER = object()
config.PYRO_STORAGE = tempfile.gettempdir()
def ns_group_and_id(idstr, defaultnsgroup=_MARKER):
try:
nsgroup, nsid = idstr.rsplit('.', 1)
except ValueError:
if defaultnsgroup is _MARKER:
nsgroup = config.PYRO_NS_DEFAULTGROUP
else:
nsgroup = defaultnsgroup
nsid = idstr
if nsgroup is not None and not nsgroup.startswith(':'):
nsgroup = ':' + nsgroup
return nsgroup, nsid
def host_and_port(hoststr):
if not hoststr:
return None, None
try:
hoststr, port = hoststr.split(':')
except ValueError:
port = None
else:
port = int(port)
return hoststr, port
_DAEMONS = {}
def _get_daemon(daemonhost, start=True):
if not daemonhost in _DAEMONS:
if not start:
raise Exception('no daemon for %s' % daemonhost)
if not _DAEMONS:
core.initServer(banner=0)
host, port = host_and_port(daemonhost)
daemon = core.Daemon(host=host, port=port)
_DAEMONS[daemonhost] = daemon
return _DAEMONS[daemonhost]
def locate_ns(nshost):
"""locate and return the pyro name server to the daemon"""
core.initClient(banner=False)
return naming.NameServerLocator().getNS(*host_and_port(nshost))
def register_object(object, nsid, defaultnsgroup=_MARKER,
daemonhost=None, nshost=None):
"""expose the object as a pyro object and register it in the name-server
return the pyro daemon object
"""
nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
daemon = _get_daemon(daemonhost)
nsd = locate_ns(nshost)
# make sure our namespace group exists
try:
nsd.createGroup(nsgroup)
except errors.NamingError:
pass
daemon.useNameServer(nsd)
# use Delegation approach
impl = core.ObjBase()
impl.delegateTo(object)
daemon.connect(impl, '%s.%s' % (nsgroup, nsid))
_LOGGER.info('registered %s a pyro object using group %s and id %s',
object, nsgroup, nsid)
return daemon
def ns_unregister(nsid, defaultnsgroup=_MARKER, nshost=None):
"""unregister the object with the given nsid from the pyro name server"""
nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
try:
nsd = locate_ns(nshost)
except errors.PyroError, ex:
# name server not responding
_LOGGER.error('can\'t locate pyro name server: %s', ex)
else:
try:
nsd.unregister('%s.%s' % (nsgroup, nsid))
_LOGGER.info('%s unregistered from pyro name server', nsid)
except errors.NamingError:
_LOGGER.warning('%s not registered in pyro name server', nsid)
def ns_get_proxy(nsid, defaultnsgroup=_MARKER, nshost=None):
nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
# resolve the Pyro object
try:
nsd = locate_ns(nshost)
pyrouri = nsd.resolve('%s.%s' % (nsgroup, nsid))
except errors.ProtocolError, ex:
raise errors.PyroError(
'Could not connect to the Pyro name server (host: %s)' % nshost)
except errors.NamingError:
raise errors.PyroError(
'Could not get proxy for %s (not registered in Pyro), '
'you may have to restart your server-side application' % nsid)
return core.getProxyForURI(pyrouri)
def set_pyro_log_threshold(level):
pyrologger = logging.getLogger('Pyro.%s' % str(id(util.Log)))
# remove handlers so only the root handler is used
pyrologger.handlers = []
pyrologger.setLevel(level)
|