Merge "Pecan: Add missing emulated bulk create method"
This commit is contained in:
commit
863fb129f9
@ -60,7 +60,6 @@ class ItemController(utils.NeutronPecanController):
|
|||||||
def put(self, *args, **kwargs):
|
def put(self, *args, **kwargs):
|
||||||
neutron_context = request.context['neutron_context']
|
neutron_context = request.context['neutron_context']
|
||||||
resources = request.context['resources']
|
resources = request.context['resources']
|
||||||
# TODO(kevinbenton): bulk?
|
|
||||||
# Bulk update is not supported, 'resources' always contains a single
|
# Bulk update is not supported, 'resources' always contains a single
|
||||||
# elemenet
|
# elemenet
|
||||||
data = {self.resource: resources[0]}
|
data = {self.resource: resources[0]}
|
||||||
|
@ -18,6 +18,8 @@ import copy
|
|||||||
import functools
|
import functools
|
||||||
|
|
||||||
from neutron_lib import constants
|
from neutron_lib import constants
|
||||||
|
from oslo_log import log as logging
|
||||||
|
from oslo_utils import excutils
|
||||||
import pecan
|
import pecan
|
||||||
from pecan import request
|
from pecan import request
|
||||||
|
|
||||||
@ -30,6 +32,8 @@ from neutron_lib import exceptions
|
|||||||
|
|
||||||
# Utility functions for Pecan controllers.
|
# Utility functions for Pecan controllers.
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Fakecode(object):
|
class Fakecode(object):
|
||||||
co_varnames = ()
|
co_varnames = ()
|
||||||
@ -236,8 +240,32 @@ class NeutronPecanController(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def plugin_bulk_creator(self):
|
def plugin_bulk_creator(self):
|
||||||
return getattr(self.plugin,
|
native = getattr(self.plugin,
|
||||||
'%s_bulk' % self._plugin_handlers[self.CREATE])
|
'%s_bulk' % self._plugin_handlers[self.CREATE],
|
||||||
|
None)
|
||||||
|
# NOTE(kevinbenton): this flag is just to make testing easier since we
|
||||||
|
# don't have any in-tree plugins without native bulk support
|
||||||
|
if getattr(self.plugin, '_FORCE_EMULATED_BULK', False) or not native:
|
||||||
|
return self._emulated_bulk_creator
|
||||||
|
return native
|
||||||
|
|
||||||
|
def _emulated_bulk_creator(self, context, **kwargs):
|
||||||
|
objs = []
|
||||||
|
body = kwargs[self.collection]
|
||||||
|
try:
|
||||||
|
for item in body[self.collection]:
|
||||||
|
objs.append(self.plugin_creator(context, item))
|
||||||
|
return objs
|
||||||
|
except Exception:
|
||||||
|
with excutils.save_and_reraise_exception():
|
||||||
|
for obj in objs:
|
||||||
|
try:
|
||||||
|
self.plugin_deleter(context, obj['id'])
|
||||||
|
except Exception:
|
||||||
|
LOG.exception("Unable to undo bulk create for "
|
||||||
|
"%(resource)s %(id)s",
|
||||||
|
{'resource': self.collection,
|
||||||
|
'id': obj['id']})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def plugin_deleter(self):
|
def plugin_deleter(self):
|
||||||
|
@ -494,6 +494,47 @@ class TestResourceController(TestRootController):
|
|||||||
self.assertIn('ports', json_body)
|
self.assertIn('ports', json_body)
|
||||||
self.assertEqual(2, len(json_body['ports']))
|
self.assertEqual(2, len(json_body['ports']))
|
||||||
|
|
||||||
|
def test_emulated_bulk_create(self):
|
||||||
|
self.plugin._FORCE_EMULATED_BULK = True
|
||||||
|
response = self.app.post_json(
|
||||||
|
'/v2.0/ports.json',
|
||||||
|
params={'ports': [{'network_id': self.port['network_id'],
|
||||||
|
'admin_state_up': True,
|
||||||
|
'tenant_id': 'tenid'},
|
||||||
|
{'network_id': self.port['network_id'],
|
||||||
|
'admin_state_up': True,
|
||||||
|
'tenant_id': 'tenid'}]
|
||||||
|
},
|
||||||
|
headers={'X-Project-Id': 'tenid'})
|
||||||
|
self.assertEqual(response.status_int, 201)
|
||||||
|
json_body = jsonutils.loads(response.body)
|
||||||
|
self.assertIn('ports', json_body)
|
||||||
|
self.assertEqual(2, len(json_body['ports']))
|
||||||
|
|
||||||
|
def test_emulated_bulk_create_rollback(self):
|
||||||
|
self.plugin._FORCE_EMULATED_BULK = True
|
||||||
|
response = self.app.post_json(
|
||||||
|
'/v2.0/ports.json',
|
||||||
|
params={'ports': [{'network_id': self.port['network_id'],
|
||||||
|
'admin_state_up': True,
|
||||||
|
'tenant_id': 'tenid'},
|
||||||
|
{'network_id': self.port['network_id'],
|
||||||
|
'admin_state_up': True,
|
||||||
|
'tenant_id': 'tenid'},
|
||||||
|
{'network_id': 'bad_net_id',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'tenant_id': 'tenid'}]
|
||||||
|
},
|
||||||
|
headers={'X-Project-Id': 'tenid'},
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(response.status_int, 400)
|
||||||
|
response = self.app.get(
|
||||||
|
'/v2.0/ports.json',
|
||||||
|
headers={'X-Project-Id': 'tenid'})
|
||||||
|
# all ports should be rolled back from above so we are just left
|
||||||
|
# with the one created in setup
|
||||||
|
self.assertEqual(1, len(jsonutils.loads(response.body)['ports']))
|
||||||
|
|
||||||
def test_bulk_create_one_item(self):
|
def test_bulk_create_one_item(self):
|
||||||
response = self.app.post_json(
|
response = self.app.post_json(
|
||||||
'/v2.0/ports.json',
|
'/v2.0/ports.json',
|
||||||
|
Loading…
Reference in New Issue
Block a user