Browse Source

feat(api): Add multi env support to group tags endpint (#11819)

Jess MacQueen 6 years ago
parent
commit
af167a20eb

+ 16 - 12
src/sentry/api/endpoints/group_tags.py

@@ -3,13 +3,12 @@ from __future__ import absolute_import
 from rest_framework.response import Response
 from rest_framework.response import Response
 
 
 from sentry import tagstore
 from sentry import tagstore
-from sentry.api.base import EnvironmentMixin
 from sentry.api.bases.group import GroupEndpoint
 from sentry.api.bases.group import GroupEndpoint
+from sentry.api.helpers.environments import get_environments
 from sentry.api.serializers import serialize
 from sentry.api.serializers import serialize
-from sentry.models import Environment
 
 
 
 
-class GroupTagsEndpoint(GroupEndpoint, EnvironmentMixin):
+class GroupTagsEndpoint(GroupEndpoint):
     def get(self, request, group):
     def get(self, request, group):
 
 
         # optional queryparam `key` can be used to get results
         # optional queryparam `key` can be used to get results
@@ -25,14 +24,19 @@ class GroupTagsEndpoint(GroupEndpoint, EnvironmentMixin):
         else:
         else:
             value_limit = 10
             value_limit = 10
 
 
-        try:
-            environment_id = self._get_environment_id_from_request(
-                request, group.project.organization_id)
-        except Environment.DoesNotExist:
-            tag_keys = []
-        else:
-            tag_keys = tagstore.get_group_tag_keys_and_top_values(
-                group.project_id, group.id, environment_id and [environment_id], keys=keys,
-                value_limit=value_limit)
+        use_snuba = request.GET.get('enable_snuba') == '1'
+
+        environment_ids = [e.id for e in get_environments(request, group.project.organization)]
+
+        if not use_snuba:
+            # TODO(jess): This is just to ensure we're not breaking the old
+            # issue page somehow -- non-snuba tagstore versions will raise
+            # if more than one env is passed
+            if environment_ids:
+                environment_ids = environment_ids[:1]
+
+        tag_keys = tagstore.get_group_tag_keys_and_top_values(
+            group.project_id, group.id, environment_ids, keys=keys,
+            value_limit=value_limit)
 
 
         return Response(serialize(tag_keys, request.user))
         return Response(serialize(tag_keys, request.user))

+ 47 - 30
tests/sentry/api/endpoints/test_group_tags.py

@@ -5,6 +5,37 @@ from sentry.testutils import APITestCase
 
 
 
 
 class GroupTagsTest(APITestCase):
 class GroupTagsTest(APITestCase):
+    def _create_tags(self, group, environment_id=None):
+        for key, values in group.data['tags']:
+            tagstore.create_tag_key(
+                project_id=group.project_id,
+                environment_id=environment_id,
+                key=key,
+            )
+            tagstore.create_group_tag_key(
+                project_id=group.project_id,
+                group_id=group.id,
+                environment_id=environment_id,
+                key=key,
+            )
+
+            if not isinstance(values, list):
+                values = [values]
+            for value in values:
+                tagstore.create_tag_value(
+                    project_id=group.project_id,
+                    environment_id=environment_id,
+                    key=key,
+                    value=value,
+                )
+                tagstore.create_group_tag_value(
+                    project_id=group.project_id,
+                    group_id=group.id,
+                    environment_id=environment_id,
+                    key=key,
+                    value=value,
+                )
+
     def test_simple(self):
     def test_simple(self):
         this_group = self.create_group()
         this_group = self.create_group()
         this_group.data['tags'] = (['foo', ['bar', 'quux']], ['biz', 'baz'], [
         this_group.data['tags'] = (['foo', ['bar', 'quux']], ['biz', 'baz'], [
@@ -17,35 +48,7 @@ class GroupTagsTest(APITestCase):
         other_group.save()
         other_group.save()
 
 
         for group in (this_group, other_group):
         for group in (this_group, other_group):
-            for key, values in group.data['tags']:
-                tagstore.create_tag_key(
-                    project_id=group.project_id,
-                    environment_id=None,
-                    key=key,
-                )
-                tagstore.create_group_tag_key(
-                    project_id=group.project_id,
-                    group_id=group.id,
-                    environment_id=None,
-                    key=key,
-                )
-
-                if not isinstance(values, list):
-                    values = [values]
-                for value in values:
-                    tagstore.create_tag_value(
-                        project_id=group.project_id,
-                        environment_id=None,
-                        key=key,
-                        value=value,
-                    )
-                    tagstore.create_group_tag_value(
-                        project_id=group.project_id,
-                        group_id=group.id,
-                        environment_id=None,
-                        key=key,
-                        value=value,
-                    )
+            self._create_tags(group)
 
 
         self.login_as(user=self.user)
         self.login_as(user=self.user)
 
 
@@ -84,4 +87,18 @@ class GroupTagsTest(APITestCase):
         self.login_as(user=self.user)
         self.login_as(user=self.user)
         url = u'/api/0/issues/{}/tags/'.format(this_group.id)
         url = u'/api/0/issues/{}/tags/'.format(this_group.id)
         response = self.client.get(url, {'environment': 'notreal'}, format='json')
         response = self.client.get(url, {'environment': 'notreal'}, format='json')
-        assert response.data == []
+        assert response.status_code == 404
+
+    def test_valid_env(self):
+        group = self.create_group()
+        group.data['tags'] = (['foo', 'bar'], ['biz', 'baz'])
+        group.save()
+
+        env = self.create_environment(project=group.project)
+        self._create_tags(group, environment_id=env.id)
+
+        self.login_as(user=self.user)
+        url = u'/api/0/issues/{}/tags/'.format(group.id)
+        response = self.client.get(url, {'environment': env.name}, format='json')
+        assert response.status_code == 200
+        assert len(response.data) == 2

+ 38 - 0
tests/snuba/api/endpoints/test_group_tags.py

@@ -0,0 +1,38 @@
+from __future__ import absolute_import
+
+from datetime import timedelta
+from django.utils import timezone
+from sentry.testutils import APITestCase, SnubaTestCase
+
+
+class GroupTagsTest(APITestCase, SnubaTestCase):
+    def test_multi_env(self):
+        now = timezone.now()
+        min_ago = now - timedelta(minutes=1)
+        group = self.create_group(first_seen=min_ago, last_seen=now)
+        env = self.create_environment(project=group.project, name='prod')
+        env2 = self.create_environment(project=group.project, name='staging')
+        self.create_event(
+            group=group,
+            tags=[['foo', 'bar'], ['environment', env.name]],
+            datetime=min_ago,
+        )
+        self.create_event(
+            group=group,
+            tags=[['biz', 'baz'], ['environment', env2.name]],
+            datetime=min_ago,
+        )
+
+        self.login_as(user=self.user)
+        url = u'/api/0/issues/{}/tags/?enable_snuba=1'.format(group.id)
+        response = self.client.get(
+            '%s&environment=%s&environment=%s' % (url, env.name, env2.name),
+            format='json'
+        )
+        assert response.status_code == 200
+        assert sorted([
+            (tag['key'], tag['uniqueValues']) for tag in response.data
+        ], key=lambda x: x[0]) == [
+            ('biz', 1), ('environment', 2), ('foo', 1)
+        ]
+        assert len(response.data) == 3