Added support to v2

Zaqarclient v2 currently has missing features that involve the
management of subscriptions, but in order to these to work it is
necessary to add other features such as 'queues', 'messages',
'claims', 'pools' and 'flavors'. I added 'queues' and 'messages' as a
priorital step before start working with the other features and with
subscriptions as well.

Change-Id: Iea082cbf9e1d0e4a745bc10e41e1206af6132fad
This commit is contained in:
dynarro 2015-08-04 21:50:29 +02:00 committed by Fei Long Wang
parent b369538b33
commit 313f175471
19 changed files with 470 additions and 1 deletions

View File

@ -40,9 +40,13 @@ zaqarclient.transport =
http.v1.1 = zaqarclient.transport.http:HttpTransport
https.v1.1 = zaqarclient.transport.http:HttpTransport
http.v2 = zaqarclient.transport.http:HttpTransport
https.v2 = zaqarclient.transport.http:HttpTransport
zaqarclient.api =
queues.v1 = zaqarclient.queues.v1.api:V1
queues.v1.1 = zaqarclient.queues.v1.api:V1_1
queues.v2 = zaqarclient.queues.v2.api:V2
openstack.messaging.v1 =
queue_list = zaqarclient.queues.v1.cli:ListQueues

View File

View File

@ -0,0 +1,26 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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 queues
from zaqarclient.transport import http
class QueuesV2QueueHttpFunctionalTest(queues.QueuesV2QueueFunctionalTest):
is_functional = True
transport_cls = http.HttpTransport
url = 'http://127.0.0.1:8888'
version = 2

View File

View File

@ -0,0 +1,55 @@
# Copyright 2014 IBM Corp.
#
# 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 mock
import ddt
from zaqarclient.queues import client
from zaqarclient.queues.v1 import core
from zaqarclient.tests import base
from zaqarclient.transport import errors
VERSIONS = [2]
@ddt.ddt
class TestClient(base.TestBase):
@ddt.data(*VERSIONS)
def test_transport(self, version):
cli = client.Client('http://example.com',
version, {})
self.assertIsNotNone(cli.transport())
@ddt.data(*VERSIONS)
def test_health_ok(self, version):
cli = client.Client('http://example.com',
version, {})
with mock.patch.object(core, 'health', autospec=True) as core_health:
core_health.return_value = None
self.assertTrue(cli.health())
@ddt.data(*VERSIONS)
def test_health_bad(self, version):
cli = client.Client('http://example.com',
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())

View File

@ -0,0 +1,20 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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 tests.unit.queues.v1 import test_core
class TestV2Core(test_core.TestV1Core):
pass

View File

@ -0,0 +1,109 @@
# Copyright (c) 2013 Rackspace, Inc.
#
# 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 tests.unit.queues.v1 import test_message as msg
from zaqarclient.queues.v1 import iterator as iterate
from zaqarclient.queues.v1 import message
from zaqarclient.transport import http
from zaqarclient.transport import response
class TestMessageIterator(msg.TestMessageIterator):
def test_no_next_iteration(self):
messages = {'links': [],
'messages': [{
'href': '/v2/queues/mine/messages/123123423',
'ttl': 800,
'age': 790,
'body': {'event': 'ActivateAccount',
'mode': 'active'}
}]
}
iterator = iterate._Iterator(self.queue.client,
messages,
'messages',
message.create_object(self.queue))
iterated = [msg for msg in iterator]
self.assertEqual(len(iterated), 1)
def test_stream(self):
messages = {'links': [],
'messages': [{
'href': '/v2/queues/mine/messages/123123423',
'ttl': 800,
'age': 790,
'body': {'event': 'ActivateAccount',
'mode': 'active'}
}]
}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(messages))
send_method.return_value = resp
# NOTE(flaper87): The first iteration will return 1 message
# and then call `_next_page` which will use the rel-next link
# to get a new set of messages.
link = {'rel': 'next',
'href': "/v2/queues/mine/messages?marker=6244-244224-783"}
messages['links'].append(link)
iterator = iterate._Iterator(self.queue.client,
messages,
'messages',
message.create_object(self.queue))
iterated = [msg for msg in iterator.stream()]
self.assertEqual(len(iterated), 2)
def test_iterator_respect_paging(self):
messages = {'links': [],
'messages': [{
'href': '/v2/queues/mine/messages/123123423',
'ttl': 800,
'age': 790,
'body': {'event': 'ActivateAccount',
'mode': 'active'}
}]
}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(messages))
send_method.return_value = resp
link = {'rel': 'next',
'href': "/v2/queues/mine/messages?marker=6244-244224-783"}
messages['links'].append(link)
iterator = iterate._Iterator(self.queue.client,
messages,
'messages',
message.create_object(self.queue))
iterated = [msg for msg in iterator]
self.assertEqual(len(iterated), 1)
class QueuesV2MessageHttpUnitTest(msg.QueuesV1MessageHttpUnitTest):
transport_cls = http.HttpTransport
url = 'http://127.0.0.1:8888/v2'
version = 2

View File

@ -0,0 +1,27 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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 tests.unit.queues.v1 import test_queues
from zaqarclient.transport import http
class QueuesV2QueueHttpUnitTest(test_queues.QueuesV1QueueHttpUnitTest):
transport_cls = http.HttpTransport
url = 'http://127.0.0.1:8888/v2'
version = 2
def test_queue_exists(self):
pass

View File

@ -70,9 +70,11 @@ the underlying API, although not recommended.
"""
from zaqarclient import errors
from zaqarclient.queues.v1 import client as cv1
from zaqarclient.queues.v2 import client as cv2
_CLIENTS = {1: cv1.Client,
1.1: cv1.Client}
1.1: cv1.Client,
2: cv2.Client}
def Client(url=None, version=None, conf=None):

View File

View File

@ -0,0 +1,6 @@
from zaqarclient.queues.v1 import api
class V2(api.V1_1):
label = 'v2'
schema = api.V1_1.schema.copy()

View File

@ -0,0 +1,44 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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 uuid
from zaqarclient.queues.v1 import client
class Client(client.Client):
"""Client base class
:param url: Zaqar's instance base url.
:type url: `six.text_type`
:param version: API Version pointing to.
:type version: `int`
:param options: Extra options:
- client_uuid: Custom client uuid. A new one
will be generated, if not passed.
- auth_opts: Authentication options:
- backend
- options
:type options: `dict`
"""
def __init__(self, url=None, version=2, conf=None):
self.conf = conf or {}
self.api_url = url
self.api_version = version
self.auth_opts = self.conf.get('auth_opts', {})
self.client_uuid = self.conf.get('client_uuid',
uuid.uuid4().hex)

View File

@ -0,0 +1,43 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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.
"""
This module defines a lower level API for queues' v2. This level of the
API is responsible for packing up the final request, sending it to the server
and handling asynchronous requests.
Functions present in this module assume that:
1. The transport instance is ready to `send` the
request to the server.
2. Transport instance holds the conf instance to use for this
request.
"""
from zaqarclient.queues.v1 import core
queue_create = core.queue_create
queue_exists = core.queue_exists
queue_get = core.queue_get
queue_get_metadata = core.queue_get_metadata
queue_set_metadata = core.queue_set_metadata
queue_get_stats = core.queue_get_stats
queue_delete = core.queue_delete
queue_list = core.queue_list
message_list = core.message_list
message_post = core.message_post
message_delete = core.message_delete
message_delete_many = core.message_delete_many

View File

@ -0,0 +1,5 @@
from zaqarclient.queues.v1 import message
class Message(message.Message):
pass

View File

@ -0,0 +1,39 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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 import errors
from zaqarclient.queues.v1 import queues
from zaqarclient.queues.v2 import core
from zaqarclient.queues.v2 import message
class Queue(queues.Queue):
def message(self, message_id):
"""Gets a message by id
:param message_id: Message's reference
:type message_id: `six.text_type`
:returns: A message
:rtype: `dict`
"""
req, trans = self.client._request_and_transport()
if self.client.api_version >= 2:
raise errors.InvalidOperation("Unavailable on versions >= 2")
else:
msg = core.message_get(trans, req, self._name,
message_id)
return message.Message(self, **msg)

View File

@ -461,3 +461,7 @@ class QueuesV1_1QueueFunctionalTest(QueuesV1QueueFunctionalTest):
remaining = queue.messages(echo=True)
self.assertEqual(1, len(list(remaining)))
class QueuesV2QueueFunctionalTest(QueuesV1_1QueueFunctionalTest):
pass

View File

View File

@ -0,0 +1,61 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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.v1 import messages
from zaqarclient.transport import response
class QueuesV2MessageUnitTest(messages.QueuesV1MessageUnitTest):
def test_message_delete(self):
returned = {
'href': '/v2/queues/fizbit/messages/50b68a50d6f5b8c8a7c62b01',
'ttl': 800,
'age': 790,
'body': {'event': 'ActivateAccount', 'mode': 'active'}
}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(returned))
send_method.return_value = resp
msg = self.queue.message('50b68a50d6f5b8c8a7c62b01')
send_method.return_value = None
self.assertIsNone(msg.delete())
def test_message_delete_with_claim(self):
returned = {
'href': '/v2/queues/fizbit/messages/50b68a50d6?claim_id=5388b5dd0',
'ttl': 800,
'age': 790,
'body': {'event': 'ActivateAccount', 'mode': 'active'}
}
with mock.patch.object(self.transport, 'send',
autospec=True) as send_method:
resp = response.Response(None, json.dumps(returned))
send_method.return_value = resp
msg = self.queue.message('50b68a50d6')
send_method.return_value = None
self.assertIsNone(msg.delete())

View File

@ -0,0 +1,24 @@
# Copyright (c) 2013 Red Hat, Inc.
#
# 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.v1 import queues
class QueuesV2QueueUnitTest(queues.QueuesV1_1QueueUnitTest):
pass
class QueuesV2QueueFunctionalTest(queues.QueuesV1_1QueueFunctionalTest):
pass