blob: e2e266ea572a2839b8b57814aea1aee16ef9e221 [file] [log] [blame]
Mitja Nikolaus1280ef42018-08-21 16:20:07 +02001"""REST API for accessing heartbeats."""
2
Dirk Vogte1784882016-10-13 16:09:38 +02003from django.shortcuts import get_object_or_404
Mitja Nikolaus1280ef42018-08-21 16:20:07 +02004from django.utils.decorators import method_decorator
5from drf_yasg import openapi
6from drf_yasg.utils import swagger_auto_schema
7from rest_framework import generics, status
8from rest_framework.exceptions import NotFound, ValidationError
9
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020010from crashreports.models import HeartBeat
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020011from crashreports.permissions import HasRightsOrIsDeviceOwnerDeviceCreation
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020012from crashreports.response_descriptions import default_desc
13from crashreports.serializers import HeartBeatSerializer
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020014
Dirk Vogte1784882016-10-13 16:09:38 +020015# TODO: There is quite some code duplciation between here and the corresponding
16# crashreport code. We should revisit this later.
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020017
Dirk Vogte1784882016-10-13 16:09:38 +020018
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020019@method_decorator(
20 name="get",
21 decorator=swagger_auto_schema(operation_description="List heartbeats"),
22)
23@method_decorator(
24 name="post",
25 decorator=swagger_auto_schema(
26 operation_description="Create a heartbeat",
27 request_body=HeartBeatSerializer,
28 responses=dict(
29 [
30 default_desc(ValidationError),
31 (
32 status.HTTP_404_NOT_FOUND,
33 openapi.Response(
34 "No device with the given uuid could be found."
35 ),
36 ),
37 ]
38 ),
39 ),
40)
Dirk Vogte1784882016-10-13 16:09:38 +020041class ListCreateView(generics.ListCreateAPIView):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020042 """Endpoint for listing heartbeats and creating new heartbeats."""
43
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020044 queryset = HeartBeat.objects.all()
45 paginate_by = 20
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020046 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020047 serializer_class = HeartBeatSerializer
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020048 filter_fields = ("device", "build_fingerprint", "radio_version")
Dirk Vogte1784882016-10-13 16:09:38 +020049
50 def get(self, *args, **kwargs):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020051 """Override device__uuid parameter with uuid."""
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020052 if "uuid" in kwargs:
Dirk Vogte1784882016-10-13 16:09:38 +020053 self.queryset = HeartBeat.objects.filter(
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020054 device__uuid=kwargs["uuid"]
55 )
Dirk Vogte1784882016-10-13 16:09:38 +020056 return generics.ListCreateAPIView.get(self, *args, **kwargs)
57
58
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020059@method_decorator(
60 name="get",
61 decorator=swagger_auto_schema(
62 operation_description="Get a heartbeat",
63 responses=dict([default_desc(NotFound)]),
64 ),
65)
66@method_decorator(
67 name="put",
68 decorator=swagger_auto_schema(
69 operation_description="Update a heartbeat",
70 responses=dict([default_desc(NotFound), default_desc(ValidationError)]),
71 ),
72)
73@method_decorator(
74 name="patch",
75 decorator=swagger_auto_schema(
76 operation_description="Partially update a heartbeat",
77 responses=dict([default_desc(NotFound), default_desc(ValidationError)]),
78 ),
79)
80@method_decorator(
81 name="delete",
82 decorator=swagger_auto_schema(
83 operation_description="Delete a heartbeat",
84 responses=dict([default_desc(NotFound)]),
85 ),
86)
Dirk Vogte1784882016-10-13 16:09:38 +020087class RetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020088 """Endpoint for retrieving, updating and deleting heartbeats."""
89
90 # pylint: disable=too-many-ancestors
91
Dirk Vogte1784882016-10-13 16:09:38 +020092 queryset = HeartBeat.objects.all()
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020093 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
Dirk Vogte1784882016-10-13 16:09:38 +020094 serializer_class = HeartBeatSerializer
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020095 multiple_lookup_fields = {"id", "device__uuid", "device_local_id"}
Dirk Vogte1784882016-10-13 16:09:38 +020096
97 def get_object(self):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020098 """Retrieve a heartbeat."""
Dirk Vogte1784882016-10-13 16:09:38 +020099 queryset = self.get_queryset()
Mitja Nikolaus1280ef42018-08-21 16:20:07 +0200100 query_filter = {}
Dirk Vogte1784882016-10-13 16:09:38 +0200101 for field in self.multiple_lookup_fields:
102 if field in self.kwargs:
Mitja Nikolaus1280ef42018-08-21 16:20:07 +0200103 query_filter[field] = self.kwargs[field]
104 obj = get_object_or_404(queryset, **query_filter)
Dirk Vogte1784882016-10-13 16:09:38 +0200105 self.check_object_permissions(self.request, obj)
106 return obj