Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix duplicate orders on routes and escalation policies #2568

Merged
merged 19 commits into from
Jul 18, 2023

Conversation

vstpme
Copy link
Member

@vstpme vstpme commented Jul 18, 2023

What this PR does

Fix duplicate order values for models EscalationPolicy and ChannelFilter using the same approach as #2278.

  • Make internal API action move_to_position a part of OrderedModelViewSet, so all ordered model views use the same logic.
  • Make public API serializers for ordered models inherit from OrderedModelSerializer, so ordered model views are consistent with each other in public API.
  • Remove order from plugin fronted, since it's not being used anywhere. The frontend uses step indices & move_to_position action instead.
  • Make escalation snapshot use step indices instead of orders, since orders are not guaranteed to be sequential (+fix a minor off-by-one bug)

Which issue(s) this PR fixes

https://github.com/grafana/oncall-private/issues/1680

Checklist

  • Unit, integration, and e2e (if applicable) tests updated
  • Documentation added (or pr:no public docs PR label added if not required)
  • CHANGELOG.md updated (or pr:no changelog PR label added if not required)

@vstpme vstpme added the pr:no public docs Added to a PR that does not require public documentation updates label Jul 18, 2023
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to user notification migration from the previous PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to user notification migration from the previous PR.

)
ordering = ["alert_receive_channel_id", "is_default", "order"]
constraints = [
models.UniqueConstraint(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a unique constraint to enforce order uniqueness on DB level for ChannelFilter

class Meta:
ordering = ["order"]
constraints = [
models.UniqueConstraint(fields=["escalation_chain_id", "order"], name="unique_escalation_policy_order")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a unique constraint to enforce order uniqueness on DB level for EscalationPolicy

@@ -27,7 +27,6 @@ class ChannelFilterSerializer(OrderedModelSerializerMixin, EagerLoadingMixin, se
queryset=TelegramToOrganizationConnector.objects, filter_field="organization", allow_null=True, required=False
)
telegram_channel_details = serializers.SerializerMethodField()
order = serializers.IntegerField(required=False)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order is not used by plugin frontend, removing it from the serializer

id = serializers.CharField(read_only=True, source="public_primary_key")
user_id = UserIdField(required=True, source="user")
position = serializers.IntegerField(required=False, source="order")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

position and manual_order are now handled by parent class OrderedModelSerializer

@@ -148,7 +148,6 @@ class ChannelFilterSerializer(BaseChannelFilterSerializer):
telegram = serializers.DictField(required=False)
routing_type = RoutingTypeField(allow_null=False, required=False, source="filtering_term_type")
routing_regex = serializers.CharField(allow_null=False, required=True, source="filtering_term")
position = serializers.IntegerField(required=False, source="order")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

position and manual_order are now handled by parent class OrderedModelSerializer

@@ -141,38 +141,6 @@ def handle_exception(self, exc):
return super().handle_exception(exc)


class OrderedModelSerializerMixin:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mixin is superseded by OrderedModelSerializer

@@ -64,7 +64,6 @@ const ChannelFilterForm = observer((props: ChannelFilterFormProps) => {
const onUpdateClickCallback = useCallback(() => {
(id === 'new'
? alertReceiveChannelStore.createChannelFilter({
order: 0,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order is set by backend here

@@ -4,7 +4,6 @@ import { TelegramChannel } from 'models/telegram_channel/telegram_channel.types'

export interface ChannelFilter {
id: string;
order: number;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plugin frontend doesn't use order anywhere (it uses step indices and move_to_position action instead)

@vstpme vstpme marked this pull request as ready for review July 18, 2023 15:32
@vstpme vstpme requested review from a team July 18, 2023 15:32
elif self.last_active_escalation_policy_order == 0:
return [self.escalation_policies_snapshots[0]]
return self.escalation_policies_snapshots[: self.last_active_escalation_policy_order]
return self.escalation_policies_snapshots[: self.last_active_escalation_policy_order + 1]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off-by-one bug making executed_escalation_policy_snapshots smaller than it should be (it probably affects the escalation auditor task)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch 👍 thanks for patching this

Copy link
Contributor

@joeyorlando joeyorlando left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice work! the new classes in common/ordered_model deduplicate a lot of logic shared between channel filters, escalation policies, and user notification policies 🙌

elif self.last_active_escalation_policy_order == 0:
return [self.escalation_policies_snapshots[0]]
return self.escalation_policies_snapshots[: self.last_active_escalation_policy_order]
return self.escalation_policies_snapshots[: self.last_active_escalation_policy_order + 1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch 👍 thanks for patching this

engine/apps/base/tests/test_ordered_model.py Outdated Show resolved Hide resolved
@vstpme vstpme enabled auto-merge July 18, 2023 17:16
@vstpme vstpme added this pull request to the merge queue Jul 18, 2023
Merged via the queue into dev with commit 602ed53 Jul 18, 2023
@vstpme vstpme deleted the vadimkerr/fix-duplicate-order branch July 18, 2023 17:22
brojd pushed a commit that referenced this pull request Sep 18, 2024
# What this PR does

Fix duplicate `order` values for models `EscalationPolicy` and
`ChannelFilter` using the same approach as
#2278.

- Make internal API action `move_to_position` a part of
[OrderedModelViewSet](https://github.com/grafana/oncall/pull/2568/files#diff-eb62521ccbcb072d1bd2156adeadae3b5895bce6d0d54432a23db3948b0ada54R11-R34),
so all ordered model views use the same logic.
- Make public API serializers for ordered models inherit from
[OrderedModelSerializer](https://github.com/grafana/oncall/pull/2568/files#diff-d749f94af5a49adaf5074325cdfad10ddd5a52dbfd78b49582867ebb9c92fae5R6-R38),
so ordered model views are consistent with each other in public API.
- Remove `order` from plugin fronted, since it's not being used
anywhere. The frontend uses step indices & `move_to_position` action
instead.
- Make escalation snapshot use step indices instead of orders, since
orders are not guaranteed to be sequential (+fix a minor off-by-one bug)

## Which issue(s) this PR fixes

grafana/oncall-private#1680

## Checklist

- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr:no public docs Added to a PR that does not require public documentation updates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants