Add database commit for database writes when async operations are possible

If we expect a database read to arrive asynchronously on a different
thread than a database write, then any changes from the write should
be explicitly committed to the database.

Change-Id: I23ccdb2bf33b1a2d910f71b985f8a86da3824267
Closes-bug: #1499105
This commit is contained in:
Dave McCowan 2015-09-24 00:53:19 -04:00
parent 43570e1d96
commit c494c2582b
3 changed files with 18 additions and 21 deletions

View File

@ -110,6 +110,9 @@ class QuotaDriver(object):
project = res.get_or_create_project(external_project_id)
self.repo.create_or_update_by_project_id(project.id,
parsed_project_quotas)
# commit to DB to avoid async issues if the enforcer is called from
# another thread
repo.commit()
def get_project_quotas(self, external_project_id):
"""Retrieve configured quota information from database

View File

@ -622,25 +622,23 @@ class CertificatePluginManager(named.NamedExtensionManager):
def refresh_ca_table(self):
"""Refreshes the CertificateAuthority table."""
session = self.ca_repo.get_session()
updates_made = False
for plugin in plugin_utils.get_active_plugins(self):
plugin_name = utils.generate_fullname_for(plugin)
cas, offset, limit, total = self.ca_repo.get_by_create_date(
plugin_name=plugin_name,
session=session,
suppress_exception=True)
if total < 1:
# if no entries are found, then the plugin has not yet been
# queried or that plugin's entries have expired.
# Most of the time, this will be a no-op for plugins.
self.update_ca_info(plugin, session=session)
self.update_ca_info(plugin)
updates_made = True
if updates_made:
session.flush()
session.commit()
# commit to DB to avoid async issues with different threads
repos.commit()
def update_ca_info(self, cert_plugin, session=None):
def update_ca_info(self, cert_plugin):
"""Update the CA info for a particular plugin."""
plugin_name = utils.generate_fullname_for(cert_plugin)
@ -649,20 +647,18 @@ class CertificatePluginManager(named.NamedExtensionManager):
old_cas, offset, limit, total = self.ca_repo.get_by_create_date(
plugin_name=plugin_name,
suppress_exception=True,
session=session,
show_expired=True)
for old_ca in old_cas:
plugin_ca_id = old_ca.plugin_ca_id
if plugin_ca_id not in new_ca_infos.keys():
# remove CAs that no longer exist
self._delete_ca(old_ca, session=session)
self._delete_ca(old_ca)
else:
# update those that still exist
self.ca_repo.update_entity(
old_ca,
new_ca_infos[plugin_ca_id],
session=session)
new_ca_infos[plugin_ca_id])
old_ids = set([ca.plugin_ca_id for ca in old_cas])
new_ids = set(new_ca_infos.keys())
@ -670,18 +666,17 @@ class CertificatePluginManager(named.NamedExtensionManager):
# add new CAs
add_ids = new_ids - old_ids
for add_id in add_ids:
self._add_ca(plugin_name, add_id, new_ca_infos[add_id],
session=session)
self._add_ca(plugin_name, add_id, new_ca_infos[add_id])
def _add_ca(self, plugin_name, plugin_ca_id, ca_info, session=None):
def _add_ca(self, plugin_name, plugin_ca_id, ca_info):
parsed_ca = dict(ca_info)
parsed_ca['plugin_name'] = plugin_name
parsed_ca['plugin_ca_id'] = plugin_ca_id
new_ca = models.CertificateAuthority(parsed_ca)
self.ca_repo.create_from(new_ca, session=session)
self.ca_repo.create_from(new_ca)
def _delete_ca(self, ca, session=None):
self.ca_repo.delete_entity_by_id(ca.id, None, session=session)
def _delete_ca(self, ca):
self.ca_repo.delete_entity_by_id(ca.id, None)
class _CertificateEventPluginManager(named.NamedExtensionManager,

View File

@ -19,6 +19,7 @@ import testtools
from barbican.common import utils as common_utils
from barbican.model import models
from barbican.plugin.interface import certificate_manager as cm
from barbican.tests import database_utils
from barbican.tests import utils
@ -105,7 +106,7 @@ class WhenTestingCertificateEventPluginManager(testtools.TestCase):
)
class WhenTestingCertificatePluginManager(utils.BaseTestCase,
class WhenTestingCertificatePluginManager(database_utils.RepositoryTestCase,
utils.MockModelRepositoryMixin):
def setUp(self):
@ -281,11 +282,9 @@ class WhenTestingCertificatePluginManager(utils.BaseTestCase,
self.plugin_returned.get_ca_info.assert_called_once_with()
self.ca_repo.update_entity.assert_called_once_with(
ca1,
ca1_modified_info,
session=mock.ANY)
ca1_modified_info)
self.ca_repo.delete_entity_by_id.assert_called_once_with(
ca2.id,
None,
session=mock.ANY)
None)
self.ca_repo.create_from.assert_has_calls([])