Support /ping and /health for v2
Now Zaqar supports /ping and /health API, but they're missing in zaqar client. This patch will fix it. Change-Id: I34b454c486a7b4c693a540890eee48f162a07605
This commit is contained in:
parent
3152321c7a
commit
15ef3386c0
@ -94,6 +94,8 @@ openstack.messaging.v2 =
|
||||
subscription_show = zaqarclient.queues.v2.cli:ShowSubscription
|
||||
subscription_list = zaqarclient.queues.v2.cli:ListSubscriptions
|
||||
queue_signed_url = zaqarclient.queues.v2.cli:CreateSignedUrl
|
||||
messaging_ping = zaqarclient.queues.v2.cli:Ping
|
||||
messaging_health = zaqarclient.queues.v2.cli:Health
|
||||
|
||||
openstack.cli.extension =
|
||||
messaging = zaqarclient.queues.cli
|
||||
|
27
tests/functional/queues/v2/test_health.py
Normal file
27
tests/functional/queues/v2/test_health.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2016 Catalyst IT Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from zaqarclient.tests.queues import health
|
||||
from zaqarclient.transport import http
|
||||
|
||||
|
||||
class QueuesV2HealthHttpFunctionalTest(
|
||||
health.QueuesV2HealthFunctionalTest):
|
||||
|
||||
is_functional = True
|
||||
transport_cls = http.HttpTransport
|
||||
url = 'http://127.0.0.1:8888'
|
||||
version = 2
|
@ -18,15 +18,18 @@ import mock
|
||||
import ddt
|
||||
|
||||
from zaqarclient.queues import client
|
||||
from zaqarclient.queues.v1 import core
|
||||
from zaqarclient.tests import base
|
||||
from zaqarclient.tests.queues import base
|
||||
from zaqarclient.transport import errors
|
||||
from zaqarclient.transport import http
|
||||
|
||||
VERSIONS = [2]
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestClient(base.TestBase):
|
||||
class TestClient(base.QueuesTestBase):
|
||||
transport_cls = http.HttpTransport
|
||||
url = 'http://127.0.0.1:8888/v2'
|
||||
version = VERSIONS[0]
|
||||
|
||||
@ddt.data(*VERSIONS)
|
||||
def test_transport(self, version):
|
||||
@ -35,21 +38,18 @@ class TestClient(base.TestBase):
|
||||
self.assertIsNotNone(cli.transport())
|
||||
|
||||
@ddt.data(*VERSIONS)
|
||||
def test_health_ok(self, version):
|
||||
cli = client.Client('http://example.com',
|
||||
version, {"auth_opts": {'backend': 'noauth'}})
|
||||
with mock.patch.object(core, 'health', autospec=True) as core_health:
|
||||
core_health.return_value = None
|
||||
self.assertTrue(cli.health())
|
||||
def test_ping_ok(self, version):
|
||||
with mock.patch.object(self.transport, 'send',
|
||||
autospec=True) as send_method:
|
||||
send_method.return_value = None
|
||||
self.assertTrue(self.client.ping())
|
||||
|
||||
@ddt.data(*VERSIONS)
|
||||
def test_health_bad(self, version):
|
||||
cli = client.Client('http://example.com',
|
||||
version, {"auth_opts": {'backend': 'noauth'}})
|
||||
|
||||
def test_ping_bad(self, version):
|
||||
def raise_error(*args, **kwargs):
|
||||
raise errors.ServiceUnavailableError()
|
||||
|
||||
with mock.patch.object(core, 'health', autospec=True) as core_health:
|
||||
core_health.side_effect = raise_error
|
||||
self.assertFalse(cli.health())
|
||||
with mock.patch.object(self.transport, 'send',
|
||||
autospec=True) as send_method:
|
||||
send_method.side_effect = raise_error
|
||||
self.assertFalse(self.client.ping())
|
||||
|
24
tests/unit/queues/v2/test_health.py
Normal file
24
tests/unit/queues/v2/test_health.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright (c) 2016 Catalyst IT Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from zaqarclient.tests.queues import health
|
||||
from zaqarclient.transport import http
|
||||
|
||||
|
||||
class QueuesV2HealthHttpUnitTest(health.QueuesV2HealthUnitTest):
|
||||
|
||||
transport_cls = http.HttpTransport
|
||||
url = 'http://127.0.0.1:8888/v2'
|
||||
version = 2
|
@ -74,4 +74,14 @@ V2.schema.update({
|
||||
'detailed': {'type': 'boolean'}
|
||||
}
|
||||
},
|
||||
|
||||
'ping': {
|
||||
'ref': 'ping',
|
||||
'method': 'GET',
|
||||
},
|
||||
|
||||
'health': {
|
||||
'ref': 'health',
|
||||
'method': 'GET',
|
||||
},
|
||||
})
|
||||
|
@ -393,3 +393,26 @@ class CreateSignedUrl(show.ShowOne):
|
||||
data['signature'],
|
||||
data['project']
|
||||
)
|
||||
|
||||
|
||||
class Ping(show.ShowOne):
|
||||
"""Check if Zaqar server is alive or not"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".Ping")
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = _get_client(self, parsed_args)
|
||||
columns = ('Pingable', )
|
||||
return columns, utils.get_dict_properties({'pingable': client.ping()},
|
||||
columns)
|
||||
|
||||
|
||||
class Health(command.Command):
|
||||
"""Display detailed health status of Zaqar server"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".Health")
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = _get_client(self, parsed_args)
|
||||
health = client.health()
|
||||
print(json.dumps(health, indent=4, sort_keys=True))
|
||||
|
@ -92,3 +92,14 @@ class Client(client.Client):
|
||||
subscription_list,
|
||||
'subscriptions',
|
||||
subscription.create_object(self))
|
||||
|
||||
def ping(self):
|
||||
"""Gets the health status of Zaqar server."""
|
||||
req, trans = self._request_and_transport()
|
||||
return core.ping(trans, req)
|
||||
|
||||
@decorators.version(min_version=1.1)
|
||||
def health(self):
|
||||
"""Gets the detailed health status of Zaqar server."""
|
||||
req, trans = self._request_and_transport()
|
||||
return core.health(trans, req)
|
||||
|
@ -220,3 +220,42 @@ def subscription_list(transport, request, queue_name, **kwargs):
|
||||
return {'links': [], 'subscriptions': []}
|
||||
|
||||
return resp.deserialized_content
|
||||
|
||||
|
||||
def ping(transport, request, callback=None):
|
||||
"""Check the health of web head for load balancing
|
||||
|
||||
:param transport: Transport instance to use
|
||||
:type transport: `transport.base.Transport`
|
||||
:param request: Request instance ready to be sent.
|
||||
:type request: `transport.request.Request`
|
||||
:param callback: Optional callable to use as callback.
|
||||
If specified, this request will be sent asynchronously.
|
||||
(IGNORED UNTIL ASYNC SUPPORT IS COMPLETE)
|
||||
:type callback: Callable object.
|
||||
"""
|
||||
|
||||
request.operation = 'ping'
|
||||
try:
|
||||
transport.send(request)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def health(transport, request, callback=None):
|
||||
"""Get detailed health status of Zaqar server
|
||||
|
||||
:param transport: Transport instance to use
|
||||
:type transport: `transport.base.Transport`
|
||||
:param request: Request instance ready to be sent.
|
||||
:type request: `transport.request.Request`
|
||||
:param callback: Optional callable to use as callback.
|
||||
If specified, this request will be sent asynchronously.
|
||||
(IGNORED UNTIL ASYNC SUPPORT IS COMPLETE)
|
||||
:type callback: Callable object.
|
||||
"""
|
||||
|
||||
request.operation = 'health'
|
||||
resp = transport.send(request)
|
||||
return resp.deserialized_content
|
||||
|
51
zaqarclient/tests/queues/health.py
Normal file
51
zaqarclient/tests/queues/health.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2016 Catalyst IT Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import mock
|
||||
|
||||
from zaqarclient.tests.queues import base
|
||||
from zaqarclient.transport import response
|
||||
|
||||
|
||||
class QueuesV2HealthUnitTest(base.QueuesTestBase):
|
||||
|
||||
def test_health(self):
|
||||
expect_health = {u'catalog_reachable': True,
|
||||
u'redis': {u'operation_status': {},
|
||||
u'storage_reachable': True}
|
||||
}
|
||||
|
||||
with mock.patch.object(self.transport, 'send',
|
||||
autospec=True) as send_method:
|
||||
|
||||
health_content = json.dumps(expect_health)
|
||||
health_resp = response.Response(None, health_content)
|
||||
send_method.side_effect = iter([health_resp])
|
||||
|
||||
health = self.client.health()
|
||||
self.assertEqual(expect_health, health)
|
||||
|
||||
|
||||
class QueuesV2HealthFunctionalTest(base.QueuesTestBase):
|
||||
def test_ping(self):
|
||||
# NOTE(flwang): If test env is not pingable, then the test should fail
|
||||
self.assertTrue(self.client.ping())
|
||||
|
||||
def test_health(self):
|
||||
health = self.client.health()
|
||||
# NOTE(flwang): If everything is ok, then zaqar server will return a
|
||||
# JSON(dict).
|
||||
self.assertTrue(isinstance(health, dict))
|
Loading…
Reference in New Issue
Block a user