Fix race condition in V1 Records API
When listing records in the V1 API, two calls to central are made - once for records once for recordsets - if the content of either changes between the two calls, a failure can occour. Instead, we already have all the data we need so use it from the recordsets rather than make two calls Change-Id: Ic43d7e8c0d60267ec4788b63ed5f7e88e7bbe625 Closes-Bug: 1487934
This commit is contained in:
parent
3e3d4681b7
commit
eea5c1e8ad
|
@ -92,15 +92,6 @@ def _format_record_v1(record, recordset):
|
|||
return record
|
||||
|
||||
|
||||
def _fetch_domain_recordsets(context, domain_id):
|
||||
criterion = {'domain_id': domain_id}
|
||||
|
||||
central_api = central_rpcapi.CentralAPI.get_instance()
|
||||
recordsets = central_api.find_recordsets(context, criterion)
|
||||
|
||||
return dict((r['id'], r) for r in recordsets)
|
||||
|
||||
|
||||
@blueprint.route('/schemas/record', methods=['GET'])
|
||||
def get_record_schema():
|
||||
return flask.jsonify(record_schema.raw)
|
||||
|
@ -154,15 +145,12 @@ def get_records(domain_id):
|
|||
# return an empty records array instead of a domain not found
|
||||
central_api.get_domain(context, domain_id)
|
||||
|
||||
records = central_api.find_records(context, {'domain_id': domain_id})
|
||||
recordsets = central_api.find_recordsets(context, {'domain_id': domain_id})
|
||||
|
||||
recordsets = _fetch_domain_recordsets(context, domain_id)
|
||||
records = []
|
||||
|
||||
def _inner(record):
|
||||
recordset = recordsets[record['recordset_id']]
|
||||
return _format_record_v1(record, recordset)
|
||||
|
||||
records = [_inner(r) for r in records]
|
||||
for rrset in recordsets:
|
||||
records.extend([_format_record_v1(r, rrset) for r in rrset.records])
|
||||
|
||||
return flask.jsonify(records_schema.filter({'records': records}))
|
||||
|
||||
|
|
|
@ -466,7 +466,7 @@ class ApiV1RecordsTest(ApiV1Test):
|
|||
self.assertIn('records', response.json)
|
||||
self.assertEqual(4, len(response.json['records']))
|
||||
|
||||
@patch.object(central_service.Service, 'find_records',
|
||||
@patch.object(central_service.Service, 'get_domain',
|
||||
side_effect=messaging.MessagingTimeout())
|
||||
def test_get_records_timeout(self, _):
|
||||
self.get('domains/%s/records' % self.domain['id'],
|
||||
|
|
Loading…
Reference in New Issue