Browse Source

feat(tags): Add environment_id to tagstore basic get APIs (#6498)

Brett Hoerner 7 years ago
parent
commit
53ddebbcc1

+ 24 - 2
src/sentry/api/base.py

@@ -18,7 +18,7 @@ from rest_framework.views import APIView
 
 from sentry import tsdb
 from sentry.app import raven
-from sentry.models import ApiKey, AuditLogEntry
+from sentry.models import ApiKey, AuditLogEntry, Environment
 from sentry.utils.cursors import Cursor
 from sentry.utils.dates import to_datetime
 from sentry.utils.http import absolute_uri, is_valid_origin
@@ -27,7 +27,7 @@ from .authentication import ApiKeyAuthentication, TokenAuthentication
 from .paginator import Paginator
 from .permissions import NoPermission
 
-__all__ = ['DocSection', 'Endpoint', 'StatsMixin']
+__all__ = ['DocSection', 'Endpoint', 'EnvironmentMixin', 'StatsMixin']
 
 ONE_MINUTE = 60
 ONE_HOUR = ONE_MINUTE * 60
@@ -246,6 +246,28 @@ class Endpoint(APIView):
         return response
 
 
+class EnvironmentMixin(object):
+    def _get_environment_id_from_request(self, request, organization_id):
+        environment = self._get_environment_from_request(request, organization_id)
+
+        return environment and environment.id
+
+    def _get_environment_from_request(self, request, organization_id):
+        if not hasattr(request, '_cached_environment'):
+            environment_param = request.GET.get('environment')
+            if environment_param is None:
+                environment = None
+            else:
+                environment = Environment.get_for_organization_id(
+                    name=environment_param,
+                    organization_id=organization_id,
+                )
+
+            request._cached_environment = environment
+
+        return request._cached_environment
+
+
 class StatsMixin(object):
     def _parse_args(self, request):
         resolution = request.GET.get('resolution')

+ 10 - 3
src/sentry/api/endpoints/group_details.py

@@ -9,12 +9,13 @@ from rest_framework.response import Response
 
 from sentry import tsdb, tagstore
 from sentry.api import client
-from sentry.api.base import DocSection
+from sentry.api.base import DocSection, EnvironmentMixin
 from sentry.api.bases import GroupEndpoint
 from sentry.api.serializers import serialize
 from sentry.api.serializers.models.plugin import PluginSerializer
 from sentry.models import (
     Activity,
+    Environment,
     Group,
     GroupHash,
     GroupSeen,
@@ -66,7 +67,7 @@ STATUS_CHOICES = {
 }
 
 
-class GroupDetailsEndpoint(GroupEndpoint):
+class GroupDetailsEndpoint(GroupEndpoint, EnvironmentMixin):
     doc_section = DocSection.EVENTS
 
     def _get_activity(self, request, group, num):
@@ -210,7 +211,13 @@ class GroupDetailsEndpoint(GroupEndpoint):
         if last_release:
             last_release = self._get_release_info(request, group, last_release)
 
-        tags = tagstore.get_group_tag_keys(group.id, limit=100)
+        try:
+            environment_id = self._get_environment_id_from_request(
+                request, group.project.organization_id)
+        except Environment.DoesNotExist:
+            tags = []
+        else:
+            tags = tagstore.get_group_tag_keys(group.id, environment_id, limit=100)
 
         participants = list(
             User.objects.filter(

+ 12 - 5
src/sentry/api/endpoints/group_events.py

@@ -3,11 +3,11 @@ from __future__ import absolute_import
 import six
 
 from sentry import tagstore
-from sentry.api.base import DocSection
+from sentry.api.base import DocSection, EnvironmentMixin
 from sentry.api.bases import GroupEndpoint
 from sentry.api.serializers import serialize
 from sentry.api.paginator import DateTimePaginator
-from sentry.models import Event, Group
+from sentry.models import Environment, Event, Group
 from sentry.search.utils import parse_query
 from sentry.utils.apidocs import scenario, attach_scenarios
 from rest_framework.response import Response
@@ -20,7 +20,7 @@ def list_available_samples_scenario(runner):
     runner.request(method='GET', path='/issues/%s/events/' % group.id)
 
 
-class GroupEventsEndpoint(GroupEndpoint):
+class GroupEventsEndpoint(GroupEndpoint, EnvironmentMixin):
     doc_section = DocSection.EVENTS
 
     @attach_scenarios([list_available_samples_scenario])
@@ -52,8 +52,15 @@ class GroupEventsEndpoint(GroupEndpoint):
                 )
 
             if query_kwargs['tags']:
-                event_ids = tagstore.get_group_event_ids(
-                    group.project_id, group.id, query_kwargs['tags'])
+                try:
+                    environment_id = self._get_environment_id_from_request(
+                        request, group.project.organization_id)
+                except Environment.DoesNotExist:
+                    event_ids = []
+                else:
+                    event_ids = tagstore.get_group_event_ids(
+                        group.project_id, group.id, environment_id, query_kwargs['tags'])
+
                 if event_ids:
                     events = events.filter(
                         id__in=event_ids,

+ 15 - 7
src/sentry/api/endpoints/group_tagkey_details.py

@@ -5,11 +5,11 @@ import six
 from rest_framework.response import Response
 
 from sentry import tagstore
-from sentry.api.base import DocSection
+from sentry.api.base import DocSection, EnvironmentMixin
 from sentry.api.bases.group import GroupEndpoint
 from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.serializers import serialize
-from sentry.models import Group
+from sentry.models import Environment, Group
 from sentry.utils.apidocs import scenario
 
 
@@ -22,7 +22,7 @@ def list_tag_details_scenario(runner):
     )
 
 
-class GroupTagKeyDetailsEndpoint(GroupEndpoint):
+class GroupTagKeyDetailsEndpoint(GroupEndpoint, EnvironmentMixin):
     doc_section = DocSection.EVENTS
 
     # XXX: this scenario does not work for some inexplicable reasons
@@ -41,17 +41,25 @@ class GroupTagKeyDetailsEndpoint(GroupEndpoint):
         lookup_key = tagstore.prefix_reserved_key(key)
 
         try:
-            tag_key = tagstore.get_tag_key(group.project_id, lookup_key)
+            environment_id = self._get_environment_id_from_request(
+                request, group.project.organization_id)
+        except Environment.DoesNotExist:
+            # if the environment doesn't exist then the tag can't possibly exist
+            raise ResourceDoesNotExist
+
+        try:
+            tag_key = tagstore.get_tag_key(group.project_id, environment_id, lookup_key)
         except tagstore.TagKeyNotFound:
             raise ResourceDoesNotExist
 
         try:
-            group_tag_key = tagstore.get_group_tag_key(group.id, lookup_key)
+            group_tag_key = tagstore.get_group_tag_key(group.id, environment_id, lookup_key)
         except tagstore.GroupTagKeyNotFound:
             raise ResourceDoesNotExist
 
-        total_values = tagstore.get_group_tag_value_count(group.id, lookup_key)
-        top_values = tagstore.get_top_group_tag_values(group.id, lookup_key, limit=9)
+        total_values = tagstore.get_group_tag_value_count(group.id, environment_id, lookup_key)
+        top_values = tagstore.get_top_group_tag_values(
+            group.id, environment_id, lookup_key, limit=9)
 
         data = {
             'id': six.text_type(tag_key.id),

+ 11 - 4
src/sentry/api/endpoints/group_tagkey_values.py

@@ -1,13 +1,13 @@
 from __future__ import absolute_import
 
 from sentry import tagstore
-from sentry.api.base import DocSection
+from sentry.api.base import DocSection, EnvironmentMixin
 from sentry.api.bases.group import GroupEndpoint
 from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.paginator import DateTimePaginator, Paginator
 from sentry.api.serializers import serialize
 from sentry.api.serializers.models.tagvalue import UserTagValueSerializer
-from sentry.models import Group
+from sentry.models import Group, Environment
 from sentry.utils.apidocs import scenario
 
 
@@ -20,7 +20,7 @@ def list_tag_values_scenario(runner):
     )
 
 
-class GroupTagKeyValuesEndpoint(GroupEndpoint):
+class GroupTagKeyValuesEndpoint(GroupEndpoint, EnvironmentMixin):
     doc_section = DocSection.EVENTS
 
     # XXX: this scenario does not work for some inexplicable reasons
@@ -39,7 +39,14 @@ class GroupTagKeyValuesEndpoint(GroupEndpoint):
         lookup_key = tagstore.prefix_reserved_key(key)
 
         try:
-            tagstore.get_tag_key(group.project_id, lookup_key)
+            environment_id = self._get_environment_id_from_request(
+                request, group.project.organization_id)
+        except Environment.DoesNotExist:
+            # if the environment doesn't exist then the tag can't possibly exist
+            raise ResourceDoesNotExist
+
+        try:
+            tagstore.get_tag_key(group.project_id, environment_id, lookup_key)
         except tagstore.TagKeyNotFound:
             raise ResourceDoesNotExist
 

+ 14 - 4
src/sentry/api/endpoints/group_tags.py

@@ -6,20 +6,30 @@ from collections import defaultdict
 from rest_framework.response import Response
 
 from sentry import tagstore
+from sentry.api.base import EnvironmentMixin
 from sentry.api.bases.group import GroupEndpoint
 from sentry.api.serializers import serialize
+from sentry.models import Environment
 
 
-class GroupTagsEndpoint(GroupEndpoint):
+class GroupTagsEndpoint(GroupEndpoint, EnvironmentMixin):
     def get(self, request, group):
-        group_tag_keys = tagstore.get_group_tag_keys(group.id)
+        try:
+            environment_id = self._get_environment_id_from_request(
+                request, group.project.organization_id)
+        except Environment.DoesNotExist:
+            group_tag_keys = []
+        else:
+            group_tag_keys = tagstore.get_group_tag_keys(group.id, environment_id)
 
         # O(N) db access
         data = []
         all_top_values = []
         for group_tag_key in group_tag_keys:
-            total_values = tagstore.get_group_tag_value_count(group.id, group_tag_key.key)
-            top_values = tagstore.get_top_group_tag_values(group.id, group_tag_key.key, limit=10)
+            total_values = tagstore.get_group_tag_value_count(
+                group.id, environment_id, group_tag_key.key)
+            top_values = tagstore.get_top_group_tag_values(
+                group.id, environment_id, group_tag_key.key, limit=10)
 
             all_top_values.extend(top_values)
 

+ 10 - 3
src/sentry/api/endpoints/project_tagkey_details.py

@@ -3,18 +3,25 @@ from __future__ import absolute_import
 from rest_framework.response import Response
 
 from sentry import tagstore
+from sentry.api.base import EnvironmentMixin
 from sentry.api.bases.project import ProjectEndpoint
 from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.serializers import serialize
-from sentry.models import AuditLogEntryEvent
+from sentry.models import AuditLogEntryEvent, Environment
 
 
-class ProjectTagKeyDetailsEndpoint(ProjectEndpoint):
+class ProjectTagKeyDetailsEndpoint(ProjectEndpoint, EnvironmentMixin):
     def get(self, request, project, key):
         lookup_key = tagstore.prefix_reserved_key(key)
 
         try:
-            tagkey = tagstore.get_tag_key(project.id, lookup_key)
+            environment_id = self._get_environment_id_from_request(request, project.organization_id)
+        except Environment.DoesNotExist:
+            # if the environment doesn't exist then the tag can't possibly exist
+            raise ResourceDoesNotExist
+
+        try:
+            tagkey = tagstore.get_tag_key(project.id, environment_id, lookup_key)
         except tagstore.TagKeyNotFound:
             raise ResourceDoesNotExist
 

+ 10 - 3
src/sentry/api/endpoints/project_tagkey_values.py

@@ -1,14 +1,15 @@
 from __future__ import absolute_import
 
 from sentry import tagstore
-from sentry.api.base import DocSection
+from sentry.api.base import DocSection, EnvironmentMixin
 from sentry.api.bases.project import ProjectEndpoint
 from sentry.api.exceptions import ResourceDoesNotExist
 from sentry.api.paginator import DateTimePaginator
 from sentry.api.serializers import serialize
+from sentry.models import Environment
 
 
-class ProjectTagKeyValuesEndpoint(ProjectEndpoint):
+class ProjectTagKeyValuesEndpoint(ProjectEndpoint, EnvironmentMixin):
     doc_section = DocSection.PROJECTS
 
     def get(self, request, project, key):
@@ -28,7 +29,13 @@ class ProjectTagKeyValuesEndpoint(ProjectEndpoint):
         lookup_key = tagstore.prefix_reserved_key(key)
 
         try:
-            tagkey = tagstore.get_tag_key(project.id, lookup_key)
+            environment_id = self._get_environment_id_from_request(request, project.organization_id)
+        except Environment.DoesNotExist:
+            # if the environment doesn't exist then the tag can't possibly exist
+            raise ResourceDoesNotExist
+
+        try:
+            tagkey = tagstore.get_tag_key(project.id, environment_id, lookup_key)
         except tagstore.TagKeyNotFound:
             raise ResourceDoesNotExist
 

+ 14 - 2
src/sentry/api/endpoints/project_tags.py

@@ -5,12 +5,24 @@ import six
 from rest_framework.response import Response
 
 from sentry import tagstore
+from sentry.api.base import EnvironmentMixin
 from sentry.api.bases.project import ProjectEndpoint
+from sentry.models import Environment
 
 
-class ProjectTagsEndpoint(ProjectEndpoint):
+class ProjectTagsEndpoint(ProjectEndpoint, EnvironmentMixin):
     def get(self, request, project):
-        tag_keys = sorted(tagstore.get_tag_keys(project.id), key=lambda x: x.key)
+        try:
+            environment_id = self._get_environment_id_from_request(request, project.organization_id)
+        except Environment.DoesNotExist:
+            tag_keys = []
+        else:
+            tag_keys = sorted(
+                tagstore.get_tag_keys(
+                    project.id,
+                    environment_id,
+                ),
+                key=lambda x: x.key)
 
         data = []
         for tag_key in tag_keys:

+ 4 - 2
src/sentry/api/serializers/models/release.py

@@ -171,8 +171,10 @@ class ReleaseSerializer(Serializer):
             ).distinct())
 
         tags = {}
-        tvs = tagstore.get_tag_values(project_ids, 'sentry:release',
-                                      [o.version for o in item_list])
+        tvs = tagstore.get_tag_values(project_ids,
+                                      environment_id=None,
+                                      key='sentry:release',
+                                      values=[o.version for o in item_list])
         for tv in tvs:
             val = tags.get(tv.value)
             tags[tv.value] = {

Some files were not shown because too many files changed in this diff