Add jsonrpc client port capability
Adds the capability for the topic to contain a port to which the json rpc client will connect to. This allows for distinct json-rpc targets to be configured in an environment. Change-Id: I999316880639cd410543eb54475b0c647b35147b
This commit is contained in:
parent
ec6ba65392
commit
0a62259018
@ -82,18 +82,34 @@ class Client(object):
|
|||||||
return _can_send_version(version, self.version_cap)
|
return _can_send_version(version, self.version_cap)
|
||||||
|
|
||||||
def prepare(self, topic, version=None):
|
def prepare(self, topic, version=None):
|
||||||
|
"""Prepare the client to transmit a request.
|
||||||
|
|
||||||
|
:param topic: Topic which is being addressed. Typically this
|
||||||
|
is the hostname of the remote json-rpc service.
|
||||||
|
:param version: The RPC API version to utilize.
|
||||||
|
"""
|
||||||
|
|
||||||
host = topic.split('.', 1)[1]
|
host = topic.split('.', 1)[1]
|
||||||
|
# NOTE(TheJulia): Originally, I was worried about ip addresses being
|
||||||
|
# used, but looking at the topic split, it would have never really
|
||||||
|
# worked.
|
||||||
|
host, port = netutils.parse_host_port(host)
|
||||||
return _CallContext(
|
return _CallContext(
|
||||||
host, self.serializer, version=version,
|
host, self.serializer, version=version,
|
||||||
version_cap=self.version_cap,
|
version_cap=self.version_cap,
|
||||||
allowed_exception_namespaces=self.allowed_exception_namespaces)
|
allowed_exception_namespaces=self.allowed_exception_namespaces,
|
||||||
|
port=port)
|
||||||
|
|
||||||
|
|
||||||
class _CallContext(object):
|
class _CallContext(object):
|
||||||
"""Wrapper object for compatibility with oslo.messaging API."""
|
"""Wrapper object for compatibility with oslo.messaging API."""
|
||||||
|
|
||||||
def __init__(self, host, serializer, version=None, version_cap=None,
|
def __init__(self, host, serializer, version=None, version_cap=None,
|
||||||
allowed_exception_namespaces=()):
|
allowed_exception_namespaces=(), port=None):
|
||||||
|
if not port:
|
||||||
|
self.port = CONF.json_rpc.port
|
||||||
|
else:
|
||||||
|
self.port = int(port)
|
||||||
self.host = host
|
self.host = host
|
||||||
self.serializer = serializer
|
self.serializer = serializer
|
||||||
self.version = version
|
self.version = version
|
||||||
@ -190,7 +206,7 @@ class _CallContext(object):
|
|||||||
scheme = 'https'
|
scheme = 'https'
|
||||||
url = '%s://%s:%d' % (scheme,
|
url = '%s://%s:%d' % (scheme,
|
||||||
netutils.escape_ipv6(self.host),
|
netutils.escape_ipv6(self.host),
|
||||||
CONF.json_rpc.port)
|
self.port)
|
||||||
LOG.debug("RPC %s to %s with %s", method, url,
|
LOG.debug("RPC %s to %s with %s", method, url,
|
||||||
strutils.mask_dict_password(body))
|
strutils.mask_dict_password(body))
|
||||||
try:
|
try:
|
||||||
@ -200,7 +216,6 @@ class _CallContext(object):
|
|||||||
raise
|
raise
|
||||||
LOG.debug('RPC %s to %s returned %s', method, url,
|
LOG.debug('RPC %s to %s returned %s', method, url,
|
||||||
strutils.mask_password(result.text or '<None>'))
|
strutils.mask_password(result.text or '<None>'))
|
||||||
|
|
||||||
if not cast:
|
if not cast:
|
||||||
result = result.json()
|
result = result.json()
|
||||||
self._handle_error(result.get('error'))
|
self._handle_error(result.get('error'))
|
||||||
|
@ -395,6 +395,7 @@ class TestClient(base.IronicLibTestCase):
|
|||||||
}
|
}
|
||||||
cctx = self.client.prepare('foo.2001:db8::1')
|
cctx = self.client.prepare('foo.2001:db8::1')
|
||||||
self.assertEqual('2001:db8::1', cctx.host)
|
self.assertEqual('2001:db8::1', cctx.host)
|
||||||
|
self.assertEqual(8089, cctx.port)
|
||||||
result = cctx.call(self.context, 'do_something', answer=42)
|
result = cctx.call(self.context, 'do_something', answer=42)
|
||||||
self.assertEqual(42, result)
|
self.assertEqual(42, result)
|
||||||
mock_session.return_value.post.assert_called_once_with(
|
mock_session.return_value.post.assert_called_once_with(
|
||||||
@ -404,18 +405,35 @@ class TestClient(base.IronicLibTestCase):
|
|||||||
'params': {'answer': 42, 'context': self.ctx_json},
|
'params': {'answer': 42, 'context': self.ctx_json},
|
||||||
'id': self.context.request_id})
|
'id': self.context.request_id})
|
||||||
|
|
||||||
|
def test_call_ipv6_success_rfc2732(self, mock_session):
|
||||||
|
response = mock_session.return_value.post.return_value
|
||||||
|
response.json.return_value = {
|
||||||
|
'jsonrpc': '2.0',
|
||||||
|
'result': 42
|
||||||
|
}
|
||||||
|
cctx = self.client.prepare('foo.[2001:db8::1]:8192')
|
||||||
|
self.assertEqual('2001:db8::1', cctx.host)
|
||||||
|
result = cctx.call(self.context, 'do_something', answer=42)
|
||||||
|
self.assertEqual(42, result)
|
||||||
|
mock_session.return_value.post.assert_called_once_with(
|
||||||
|
'http://[2001:db8::1]:8192',
|
||||||
|
json={'jsonrpc': '2.0',
|
||||||
|
'method': 'do_something',
|
||||||
|
'params': {'answer': 42, 'context': self.ctx_json},
|
||||||
|
'id': self.context.request_id})
|
||||||
|
|
||||||
def test_call_success_with_version(self, mock_session):
|
def test_call_success_with_version(self, mock_session):
|
||||||
response = mock_session.return_value.post.return_value
|
response = mock_session.return_value.post.return_value
|
||||||
response.json.return_value = {
|
response.json.return_value = {
|
||||||
'jsonrpc': '2.0',
|
'jsonrpc': '2.0',
|
||||||
'result': 42
|
'result': 42
|
||||||
}
|
}
|
||||||
cctx = self.client.prepare('foo.example.com', version='1.42')
|
cctx = self.client.prepare('foo.example.com:8192', version='1.42')
|
||||||
self.assertEqual('example.com', cctx.host)
|
self.assertEqual('example.com', cctx.host)
|
||||||
result = cctx.call(self.context, 'do_something', answer=42)
|
result = cctx.call(self.context, 'do_something', answer=42)
|
||||||
self.assertEqual(42, result)
|
self.assertEqual(42, result)
|
||||||
mock_session.return_value.post.assert_called_once_with(
|
mock_session.return_value.post.assert_called_once_with(
|
||||||
'http://example.com:8089',
|
'http://example.com:8192',
|
||||||
json={'jsonrpc': '2.0',
|
json={'jsonrpc': '2.0',
|
||||||
'method': 'do_something',
|
'method': 'do_something',
|
||||||
'params': {'answer': 42, 'context': self.ctx_json,
|
'params': {'answer': 42, 'context': self.ctx_json,
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds the capability for the ``json_rpc`` client to identify and utilize
|
||||||
|
a specific port from the supplied ``topic`` field as opposed to the
|
||||||
|
default configured port.
|
Loading…
Reference in New Issue
Block a user