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_show = zaqarclient.queues.v2.cli:ShowSubscription
|
||||||
subscription_list = zaqarclient.queues.v2.cli:ListSubscriptions
|
subscription_list = zaqarclient.queues.v2.cli:ListSubscriptions
|
||||||
queue_signed_url = zaqarclient.queues.v2.cli:CreateSignedUrl
|
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 =
|
openstack.cli.extension =
|
||||||
messaging = zaqarclient.queues.cli
|
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
|
import ddt
|
||||||
|
|
||||||
from zaqarclient.queues import client
|
from zaqarclient.queues import client
|
||||||
from zaqarclient.queues.v1 import core
|
from zaqarclient.tests.queues import base
|
||||||
from zaqarclient.tests import base
|
|
||||||
from zaqarclient.transport import errors
|
from zaqarclient.transport import errors
|
||||||
|
from zaqarclient.transport import http
|
||||||
|
|
||||||
VERSIONS = [2]
|
VERSIONS = [2]
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@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)
|
@ddt.data(*VERSIONS)
|
||||||
def test_transport(self, version):
|
def test_transport(self, version):
|
||||||
@ -35,21 +38,18 @@ class TestClient(base.TestBase):
|
|||||||
self.assertIsNotNone(cli.transport())
|
self.assertIsNotNone(cli.transport())
|
||||||
|
|
||||||
@ddt.data(*VERSIONS)
|
@ddt.data(*VERSIONS)
|
||||||
def test_health_ok(self, version):
|
def test_ping_ok(self, version):
|
||||||
cli = client.Client('http://example.com',
|
with mock.patch.object(self.transport, 'send',
|
||||||
version, {"auth_opts": {'backend': 'noauth'}})
|
autospec=True) as send_method:
|
||||||
with mock.patch.object(core, 'health', autospec=True) as core_health:
|
send_method.return_value = None
|
||||||
core_health.return_value = None
|
self.assertTrue(self.client.ping())
|
||||||
self.assertTrue(cli.health())
|
|
||||||
|
|
||||||
@ddt.data(*VERSIONS)
|
@ddt.data(*VERSIONS)
|
||||||
def test_health_bad(self, version):
|
def test_ping_bad(self, version):
|
||||||
cli = client.Client('http://example.com',
|
|
||||||
version, {"auth_opts": {'backend': 'noauth'}})
|
|
||||||
|
|
||||||
def raise_error(*args, **kwargs):
|
def raise_error(*args, **kwargs):
|
||||||
raise errors.ServiceUnavailableError()
|
raise errors.ServiceUnavailableError()
|
||||||
|
|
||||||
with mock.patch.object(core, 'health', autospec=True) as core_health:
|
with mock.patch.object(self.transport, 'send',
|
||||||
core_health.side_effect = raise_error
|
autospec=True) as send_method:
|
||||||
self.assertFalse(cli.health())
|
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'}
|
'detailed': {'type': 'boolean'}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'ping': {
|
||||||
|
'ref': 'ping',
|
||||||
|
'method': 'GET',
|
||||||
|
},
|
||||||
|
|
||||||
|
'health': {
|
||||||
|
'ref': 'health',
|
||||||
|
'method': 'GET',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
@ -393,3 +393,26 @@ class CreateSignedUrl(show.ShowOne):
|
|||||||
data['signature'],
|
data['signature'],
|
||||||
data['project']
|
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,
|
subscription_list,
|
||||||
'subscriptions',
|
'subscriptions',
|
||||||
subscription.create_object(self))
|
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 {'links': [], 'subscriptions': []}
|
||||||
|
|
||||||
return resp.deserialized_content
|
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…
x
Reference in New Issue
Block a user