Keystone's update_user() method in the SQL driver processes a lot of
information about how to update users. This includes evaluating password
logic and authentication attempts for PSI-DSS. This logic is evaluated
after keystone pulls the user record from SQL and before it exits the
context manager, which performs the write.
When multiple clients are all updating the same user reference, it's
more likely they will see an HTTP 500 because of race conditions exiting
the context manager. The HTTP 500 is due to stale data when updating
password expiration for old passwords, which happens when setting a new
password for a user.
This commit attempts to handle that case more gracefully than throwing a
500 by detecting StaleDataErrors from sqlalchemy and retrying. The
identity sql backend will retry the request for clients that have
stale data change from underneath them.
keystone/tests/unit/test_backend_sql.py due to import order
differences between train and ussuri. Also adjust the expected log
message since the method path is different compared to older
releases, which have the driver name in them (e.g., Identity).
(cherry picked from commit ceae3566e83b26fd6a1679154eae9b0cef29da64)
(cherry picked from commit f47e635b8041542faa05e64606e66d2fbbc5f284)
(cherry picked from commit 5b7d4c80d484262018f937083050844648f07a11)
(cherry picked from commit 07d3a3d3ff534a5295842d4f236042b30536cd82)
(cherry picked from commit d4f48fc4e53f71d653e133104854f064fbb1b25f)
(cherry picked from commit 328cf33aab61775301adbb4c1f6abaa2f331cd94)