def get(self, request, organization, project_slug, event_id): if not features.has( "organizations:events-v2", organization, actor=request.user): return Response(status=404) try: params = self.get_filter_params(request, organization) snuba_args = self.get_snuba_query_args(request, organization, params) except OrganizationEventsError as exc: return Response({"detail": exc.message}, status=400) except NoProjects: return Response(status=404) try: project = Project.objects.get(slug=project_slug, organization_id=organization.id) except Project.DoesNotExist: return Response(status=404) # We return the requested event if we find a match regardless of whether # it occurred within the range specified event = eventstore.get_event_by_id(project.id, event_id, eventstore.full_columns) if event is None: return Response({"detail": "Event not found"}, status=404) # Scope the pagination related event ids to the current event # This ensure that if a field list/groupby conditions were provided # that we constrain related events to the query + current event values snuba_args["conditions"].extend( get_reference_event_conditions(snuba_args, event.snuba_data)) next_event = eventstore.get_next_event_id( event, conditions=snuba_args["conditions"], filter_keys=snuba_args["filter_keys"]) prev_event = eventstore.get_prev_event_id( event, conditions=snuba_args["conditions"], filter_keys=snuba_args["filter_keys"]) data = serialize(event) data["nextEventID"] = next_event[1] if next_event else None data["previousEventID"] = prev_event[1] if prev_event else None data["oldestEventID"] = self.oldest_event_id(snuba_args, event) data["latestEventID"] = self.latest_event_id(snuba_args, event) data["projectSlug"] = project_slug return Response(data)
def get(self, request, organization, project_slug, event_id): if not features.has( "organizations:events-v2", organization, actor=request.user): return Response(status=404) try: params = self.get_filter_params(request, organization) snuba_args = self.get_snuba_query_args(request, organization, params) except OrganizationEventsError as exc: return Response({"detail": exc.message}, status=400) except NoProjects: return Response(status=404) try: project = Project.objects.get(slug=project_slug, organization_id=organization.id, status=ProjectStatus.VISIBLE) except Project.DoesNotExist: return Response(status=404) # Check access to the project as this endpoint doesn't use membership checks done # get_filter_params(). if not request.access.has_project_access(project): return Response(status=404) # We return the requested event if we find a match regardless of whether # it occurred within the range specified event = eventstore.get_event_by_id(project.id, event_id) if event is None: return Response({"detail": "Event not found"}, status=404) # Scope the pagination related event ids to the current event # This ensure that if a field list/groupby conditions were provided # that we constrain related events to the query + current event values event_slug = u"{}:{}".format(project.slug, event_id) snuba_args["conditions"].extend( get_reference_event_conditions(organization, snuba_args, event_slug)) data = serialize(event) data["nextEventID"] = self.next_event_id(snuba_args, event) data["previousEventID"] = self.prev_event_id(snuba_args, event) data["oldestEventID"] = self.oldest_event_id(snuba_args, event) data["latestEventID"] = self.latest_event_id(snuba_args, event) data["projectSlug"] = project_slug return Response(data)
def get_snuba_query_args(self, request, organization, params): query = request.GET.get("query") try: snuba_args = get_snuba_query_args(query=query, params=params) except InvalidSearchQuery as exc: raise OrganizationEventsError(exc.message) sort = request.GET.getlist("sort") if sort: snuba_args["orderby"] = sort # Deprecated. `sort` should be used as it is supported by # more endpoints. orderby = request.GET.getlist("orderby") if orderby and "orderby" not in snuba_args: snuba_args["orderby"] = orderby if request.GET.get("rollup"): try: snuba_args["rollup"] = int(request.GET.get("rollup")) except ValueError: raise OrganizationEventsError("rollup must be an integer.") fields = request.GET.getlist("field")[:] if fields: try: snuba_args.update(resolve_field_list(fields, snuba_args)) except InvalidSearchQuery as exc: raise OrganizationEventsError(exc.message) reference_event_id = request.GET.get("referenceEvent") if reference_event_id: reference_event = find_reference_event(snuba_args, reference_event_id) snuba_args["conditions"] = get_reference_event_conditions( snuba_args, reference_event.snuba_data) # TODO(lb): remove once boolean search is fully functional has_boolean_op_flag = features.has("organizations:boolean-search", organization, actor=request.user) if snuba_args.pop("has_boolean_terms", False) and not has_boolean_op_flag: raise OrganizationEventsError( "Boolean search operator OR and AND not allowed in this search." ) return snuba_args
def get_snuba_query_args(self, request, organization, params): query = request.GET.get("query") try: filter = get_filter(query, params) except InvalidSearchQuery as exc: raise OrganizationEventsError(exc.message) snuba_args = { "start": filter.start, "end": filter.end, "conditions": filter.conditions, "filter_keys": filter.filter_keys, } sort = request.GET.getlist("sort") if sort: snuba_args["orderby"] = sort # Deprecated. `sort` should be used as it is supported by # more endpoints. orderby = request.GET.getlist("orderby") if orderby and "orderby" not in snuba_args: snuba_args["orderby"] = orderby if request.GET.get("rollup"): try: snuba_args["rollup"] = int(request.GET.get("rollup")) except ValueError: raise OrganizationEventsError("rollup must be an integer.") fields = request.GET.getlist("field")[:] if fields: try: snuba_args.update(resolve_field_list(fields, snuba_args)) except InvalidSearchQuery as exc: raise OrganizationEventsError(exc.message) reference_event_id = request.GET.get("referenceEvent") if reference_event_id: snuba_args["conditions"] = get_reference_event_conditions( snuba_args, reference_event_id ) return snuba_args