diff --git a/src/sentry/api/urls.py b/src/sentry/api/urls.py index ab1953a40c79e0..890e3651968d5a 100644 --- a/src/sentry/api/urls.py +++ b/src/sentry/api/urls.py @@ -87,9 +87,7 @@ OrganizationFlagsWebHookSigningSecretEndpoint, OrganizationFlagsWebHookSigningSecretsEndpoint, ) -from sentry.incidents.endpoints.organization_alert_rule_activations import ( - OrganizationAlertRuleActivationsEndpoint, -) + from sentry.incidents.endpoints.organization_alert_rule_anomalies import ( OrganizationAlertRuleAnomaliesEndpoint, ) @@ -1155,11 +1153,6 @@ def create_group_urls(name_prefix: str) -> list[URLPattern | URLResolver]: OrganizationAlertRuleDetailsEndpoint.as_view(), name="sentry-api-0-organization-alert-rule-details", ), - re_path( - r"^(?P[^\/]+)/alert-rules/(?P[^\/]+)/activations/$", - OrganizationAlertRuleActivationsEndpoint.as_view(), - name="sentry-api-0-organization-alert-rule-activations", - ), re_path( r"^(?P[^\/]+)/alert-rules/(?P[^\/]+)/anomalies/$", OrganizationAlertRuleAnomaliesEndpoint.as_view(), diff --git a/src/sentry/incidents/endpoints/organization_alert_rule_activations.py b/src/sentry/incidents/endpoints/organization_alert_rule_activations.py deleted file mode 100644 index 7632f50458e905..00000000000000 --- a/src/sentry/incidents/endpoints/organization_alert_rule_activations.py +++ /dev/null @@ -1,65 +0,0 @@ -from django.db.models import Q -from drf_spectacular.utils import extend_schema -from rest_framework.request import Request -from rest_framework.response import Response - -from sentry.api.api_owners import ApiOwner -from sentry.api.api_publish_status import ApiPublishStatus -from sentry.api.base import region_silo_endpoint -from sentry.api.paginator import OffsetPaginator -from sentry.api.serializers import serialize -from sentry.apidocs.constants import RESPONSE_FORBIDDEN, RESPONSE_NOT_FOUND, RESPONSE_UNAUTHORIZED -from sentry.apidocs.examples.metric_alert_examples import MetricAlertExamples -from sentry.apidocs.parameters import GlobalParams, MetricAlertParams -from sentry.apidocs.utils import inline_sentry_response_serializer -from sentry.incidents.endpoints.bases import OrganizationAlertRuleEndpoint -from sentry.incidents.endpoints.serializers.alert_rule_activations import ( - AlertRuleActivationsResponse, -) -from sentry.incidents.models.alert_rule import AlertRule -from sentry.models.organization import Organization - - -@extend_schema(tags=["Alerts"]) -@region_silo_endpoint -class OrganizationAlertRuleActivationsEndpoint(OrganizationAlertRuleEndpoint): - owner = ApiOwner.ISSUES - publish_status = { - "GET": ApiPublishStatus.PUBLIC, - } - - @extend_schema( - operation_id="Retrieve activations for a Metric Alert Rule", - parameters=[GlobalParams.ORG_ID_OR_SLUG, MetricAlertParams.METRIC_RULE_ID], - responses={ - 200: inline_sentry_response_serializer( - "ListAlertRuleActivations", list[AlertRuleActivationsResponse] - ), - 401: RESPONSE_UNAUTHORIZED, - 403: RESPONSE_FORBIDDEN, - 404: RESPONSE_NOT_FOUND, - }, - examples=MetricAlertExamples.GET_METRIC_ALERT_ACTIVATIONS, - ) - def get(self, request: Request, organization: Organization, alert_rule: AlertRule) -> Response: - """ - Return a list of activations for a metric alert rule. - - An activation represents a single instance of an activated alert rule being triggered. - It contains a date_added field which represents the time the alert was triggered. - Activations can be filtered by start and end parameters to return activations with date_added that falls within the specified time window. - """ - activations = alert_rule.activations.all() - start = request.GET.get("start", None) - end = request.GET.get("end", None) - if start and end: - activations = activations.filter(Q(date_added__gte=start) & Q(date_added__lte=end)) - - return self.paginate( - request, - queryset=activations, - order_by="-date_added", - paginator_cls=OffsetPaginator, - on_results=lambda x: serialize(x, request.user), - default_per_page=25, - ) diff --git a/tests/sentry/incidents/endpoints/test_organization_alert_rule_activations.py b/tests/sentry/incidents/endpoints/test_organization_alert_rule_activations.py deleted file mode 100644 index f23796cda91858..00000000000000 --- a/tests/sentry/incidents/endpoints/test_organization_alert_rule_activations.py +++ /dev/null @@ -1,89 +0,0 @@ -from datetime import timedelta -from functools import cached_property - -import pytest -from django.utils import timezone - -from sentry.api.serializers import serialize -from sentry.incidents.endpoints.serializers.alert_rule_activations import ( - AlertRuleActivationsSerializer, -) -from sentry.incidents.models.alert_rule import AlertRuleMonitorTypeInt -from sentry.testutils.abstract import Abstract -from sentry.testutils.cases import APITestCase -from sentry.testutils.helpers.datetime import freeze_time -from sentry.testutils.skips import requires_snuba - -pytestmark = [pytest.mark.sentry_metrics, requires_snuba] - - -class AlertRuleActivationsBase(APITestCase): - __test__ = Abstract(__module__, __qualname__) - - endpoint = "sentry-api-0-organization-alert-rule-activations" - - def setUp(self): - self.create_team(organization=self.organization, members=[self.user]) - self.login_as(self.user) - - @cached_property - def organization(self): - return self.create_organization() - - @cached_property - def project(self): - return self.create_project(organization=self.organization) - - @cached_property - def user(self): - return self.create_user() - - -class AlertRuleActivationsListEndpointTest(AlertRuleActivationsBase): - def test_simple(self): - alert_rule = self.create_alert_rule(monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS) - activation = self.create_alert_rule_activation( - alert_rule=alert_rule, monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS - ) - with self.feature("organizations:incidents"): - resp = self.get_success_response(self.organization.slug, alert_rule.id) - - assert resp.data == serialize(activation, serializer=AlertRuleActivationsSerializer()) - - def test_no_feature(self): - alert_rule = self.create_alert_rule() - resp = self.get_response(self.organization.slug, alert_rule.id) - assert resp.status_code == 404 - - def test_filter_by_start_end(self): - alert_rule = self.create_alert_rule(monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS) - now = timezone.now() - yesterday = now - timedelta(days=1) - last_week = now - timedelta(days=7) - with freeze_time(last_week): - old_activation = self.create_alert_rule_activation( - alert_rule=alert_rule, monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS - ) - - with freeze_time(yesterday): - yesterday_activation = self.create_alert_rule_activation( - alert_rule=alert_rule, monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS - ) - - with freeze_time(now): - new_activation = self.create_alert_rule_activation( - alert_rule=alert_rule, monitor_type=AlertRuleMonitorTypeInt.CONTINUOUS - ) - - # NOTE: order matters here. API orders by date_added - expected_activations = new_activation + yesterday_activation - - params = { - "start": now - timedelta(days=1), - "end": now + timedelta(days=1), - } - with self.feature("organizations:incidents"): - resp = self.get_response(self.organization.slug, alert_rule.id, **params) - - assert serialize(old_activation) not in resp.data - assert resp.data == serialize(expected_activations)