rabbit_definitions: Import topic permissions after exchanges #14407
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Why
Topic permissions depend on an exchange, in addition to a user and a vhost like other permissions.
This fixes a bug where an exchange imported after a topic permission that depends on it caused the following crash when Khepri is used:
{case_clause,{error,{khepri,mismatching_node, #{node_name => <<"exchange_name">>, node_props => #{payload_version => 1}, node_path => [rabbitmq,vhosts,<<"/">>,exchanges, <<"exchange_name">>], condition => {if_node_exists,false}, node_is_target => true}}}}The crash comes from the fact that the exchange code expect to either create the tree node in Khepri for that exchange, or there is an existing tree node holding an exchange tree node. Here, there was a tree node created implicitly when the topic permission was stored, but that tree node didn't have an exchange record (because the exchange was not imported yet).
How
We simply swap the import of topic permissions and exchanges.
In addition to that, we also relax the conditions used to write a new exchange record in Khepri. This is not strictly required, but this makes the code more robust (see the second commit in the branch).