Separate object-storage bulk operation service clients

Swift support bulk operation for upload archive file and bulk
delete. Service client methods for those API request are
present in account_client.py

This patch separate those methods in new client and use accordingly.

Partially implements blueprint consistent-service-method-names

Change-Id: Icceaf1bf4eddd2cf6501e76e52b54de2e105a165
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index e0216fd..c075b92 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -80,6 +80,7 @@
     def setup_clients(cls):
         super(BaseObjectTest, cls).setup_clients()
         cls.object_client = cls.os.object_client
+        cls.bulk_client = cls.os.bulk_client
         cls.container_client = cls.os.container_client
         cls.account_client = cls.os.account_client
         cls.capabilities_client = cls.os.capabilities_client
diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py
index d882731..0a72d75 100644
--- a/tempest/api/object_storage/test_account_bulk.py
+++ b/tempest/api/object_storage/test_account_bulk.py
@@ -56,11 +56,10 @@
 
     def _upload_archive(self, filepath):
         # upload an archived file
-        params = {'extract-archive': 'tar'}
         with open(filepath) as fh:
             mydata = fh.read()
-            resp, body = self.account_client.create_account(data=mydata,
-                                                            params=params)
+            resp, body = self.bulk_client.upload_archive(
+                upload_path='', data=mydata, archive_file_format='tar')
         return resp, body
 
     def _check_contents_deleted(self, container_name):
@@ -113,9 +112,7 @@
         self._upload_archive(filepath)
 
         data = '%s/%s\n%s' % (container_name, object_name, container_name)
-        params = {'bulk-delete': ''}
-        resp, body = self.account_client.delete_account(data=data,
-                                                        params=params)
+        resp, body = self.bulk_client.delete_bulk_data(data=data)
 
         # When deleting multiple files using the bulk operation, the response
         # does not contain 'content-length' header. This is the special case,
@@ -140,10 +137,8 @@
         self._upload_archive(filepath)
 
         data = '%s/%s\n%s' % (container_name, object_name, container_name)
-        params = {'bulk-delete': ''}
 
-        resp, body = self.account_client.create_account_metadata(
-            {}, data=data, params=params)
+        resp, body = self.bulk_client.delete_bulk_data_with_post(data=data)
 
         # When deleting multiple files using the bulk operation, the response
         # does not contain 'content-length' header. This is the special case,
diff --git a/tempest/clients.py b/tempest/clients.py
index e75fa79..fea7236 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -290,6 +290,8 @@
 
         self.account_client = object_storage.AccountClient(self.auth_provider,
                                                            **params)
+        self.bulk_client = object_storage.BulkMiddlewareClient(
+            self.auth_provider, **params)
         self.capabilities_client = object_storage.CapabilitiesClient(
             self.auth_provider, **params)
         self.container_client = object_storage.ContainerClient(
diff --git a/tempest/services/object_storage/__init__.py b/tempest/services/object_storage/__init__.py
index d1a61d6..1738566 100644
--- a/tempest/services/object_storage/__init__.py
+++ b/tempest/services/object_storage/__init__.py
@@ -13,10 +13,12 @@
 # the License.
 
 from tempest.services.object_storage.account_client import AccountClient
+from tempest.services.object_storage.bulk_middleware_client import \
+    BulkMiddlewareClient
 from tempest.services.object_storage.capabilities_client import \
     CapabilitiesClient
 from tempest.services.object_storage.container_client import ContainerClient
 from tempest.services.object_storage.object_client import ObjectClient
 
-__all__ = ['AccountClient', 'CapabilitiesClient', 'ContainerClient',
-           'ObjectClient']
+__all__ = ['AccountClient', 'BulkMiddlewareClient', 'CapabilitiesClient',
+           'ContainerClient', 'ObjectClient']
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index 4859e75..469e58d 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -23,41 +23,6 @@
 
 class AccountClient(rest_client.RestClient):
 
-    def create_account(self, data=None,
-                       params=None,
-                       metadata=None,
-                       remove_metadata=None,
-                       metadata_prefix='X-Account-Meta-',
-                       remove_metadata_prefix='X-Remove-Account-Meta-'):
-        """Create an account."""
-        if metadata is None:
-            metadata = {}
-        if remove_metadata is None:
-            remove_metadata = {}
-        url = ''
-        if params:
-            url += '?%s' % urllib.urlencode(params)
-
-        headers = {}
-        for key in metadata:
-            headers[metadata_prefix + key] = metadata[key]
-        for key in remove_metadata:
-            headers[remove_metadata_prefix + key] = remove_metadata[key]
-
-        resp, body = self.put(url, data, headers)
-        self.expected_success(200, resp.status)
-        return resp, body
-
-    def delete_account(self, data=None, params=None):
-        """Delete an account."""
-        url = ''
-        if params:
-            url = '?%s%s' % (url, urllib.urlencode(params))
-
-        resp, body = self.delete(url, headers={}, body=data)
-        self.expected_success(200, resp.status)
-        return resp, body
-
     def list_account_metadata(self):
         """HEAD on the storage URL
 
@@ -68,19 +33,14 @@
         return resp, body
 
     def create_account_metadata(self, metadata,
-                                metadata_prefix='X-Account-Meta-',
-                                data=None, params=None):
+                                metadata_prefix='X-Account-Meta-'):
         """Creates an account metadata entry."""
         headers = {}
         if metadata:
             for key in metadata:
                 headers[metadata_prefix + key] = metadata[key]
 
-        url = ''
-        if params:
-            url = '?%s%s' % (url, urllib.urlencode(params))
-
-        resp, body = self.post(url, headers=headers, body=data)
+        resp, body = self.post('', headers=headers, body=None)
         self.expected_success([200, 204], resp.status)
         return resp, body
 
diff --git a/tempest/services/object_storage/bulk_middleware_client.py b/tempest/services/object_storage/bulk_middleware_client.py
new file mode 100644
index 0000000..c194ea9
--- /dev/null
+++ b/tempest/services/object_storage/bulk_middleware_client.py
@@ -0,0 +1,62 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    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 tempest.lib.common import rest_client
+
+
+class BulkMiddlewareClient(rest_client.RestClient):
+
+    def upload_archive(self, upload_path, data,
+                       archive_file_format='tar', headers=None):
+        """Expand tar files into a Swift cluster.
+
+        To extract containers and objects on Swift cluster from
+        uploaded archived file. For More information please check:
+        http://docs.openstack.org/developer/swift/middleware.html#module-swift.common.middleware.bulk
+        """
+        url = '%s?extract-archive=%s' % (upload_path, archive_file_format)
+        if headers is None:
+            headers = {}
+        resp, body = self.put(url, data, headers)
+        self.expected_success(200, resp.status)
+        return resp, body
+
+    def delete_bulk_data(self, data=None, headers=None):
+        """Delete multiple objects or containers from their account.
+
+        For More information please check:
+        http://docs.openstack.org/developer/swift/middleware.html#module-swift.common.middleware.bulk
+        """
+        url = '?bulk-delete'
+
+        if headers is None:
+            headers = {}
+        resp, body = self.delete(url, headers=headers, body=data)
+        self.expected_success(200, resp.status)
+        return resp, body
+
+    def delete_bulk_data_with_post(self, data=None, headers=None):
+        """Delete multiple objects or containers with POST request.
+
+        For More information please check:
+        http://docs.openstack.org/developer/swift/middleware.html#module-swift.common.middleware.bulk
+        """
+        url = '?bulk-delete'
+
+        if headers is None:
+            headers = {}
+        resp, body = self.post(url, headers=headers, body=data)
+        self.expected_success([200, 204], resp.status)
+        return resp, body