From 44d9ef1195e3f55fbfac9b3eabc2e6d9b4ae3402 Mon Sep 17 00:00:00 2001 From: Harm Weites Date: Thu, 28 May 2020 14:17:56 +0200 Subject: [PATCH] Extremely simple /v1/health endpoint Anonymous endpoint that may be used by a container platform to verify availability of the application. Simply returns: HTTP/200 {"status":"green"} Future iterations could extend this into reflecting status of dependencies like database connections. --- app/api/tests/test_api.py | 10 ++++++++++ app/api/urls.py | 3 ++- app/api/views.py | 9 ++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/api/tests/test_api.py b/app/api/tests/test_api.py index 55303f74..5f8b08e7 100644 --- a/app/api/tests/test_api.py +++ b/app/api/tests/test_api.py @@ -29,6 +29,16 @@ def remove_all_role_mappings(): RoleMapping.objects.all().delete() +class TestHealthEndpoint(APITestCase): + @classmethod + def setUpTestData(cls): + cls.url = reverse(viewname='health') + + def test_returns_green_status_on_health_endpoint(self): + response = self.client.get(self.url, format='json') + self.assertEqual(response.data['status'], 'green') + + class TestUtilsMixin: def _patch_project(self, project, attribute, value): old_value = getattr(project, attribute, None) diff --git a/app/api/urls.py b/app/api/urls.py index b6154c57..a8941b6d 100644 --- a/app/api/urls.py +++ b/app/api/urls.py @@ -2,7 +2,7 @@ from django.urls import path from rest_framework.authtoken.views import obtain_auth_token from rest_framework.urlpatterns import format_suffix_patterns -from .views import Me, Features, Users +from .views import Me, Features, Users, Health from .views import ProjectList, ProjectDetail from .views import LabelList, LabelDetail, ApproveLabelsAPI, LabelUploadAPI from .views import DocumentList, DocumentDetail @@ -12,6 +12,7 @@ from .views import StatisticsAPI from .views import RoleMappingList, RoleMappingDetail, Roles urlpatterns = [ + path('health', Health.as_view(), name='health'), path('auth-token', obtain_auth_token), path('me', Me.as_view(), name='me'), path('features', Features.as_view(), name='features'), diff --git a/app/api/views.py b/app/api/views.py index afa030f4..d081a08c 100644 --- a/app/api/views.py +++ b/app/api/views.py @@ -11,7 +11,7 @@ from libcloud.base import DriverType, get_driver from libcloud.storage.types import ContainerDoesNotExistError, ObjectDoesNotExistError from rest_framework import generics, filters, status from rest_framework.exceptions import ParseError, ValidationError -from rest_framework.permissions import IsAuthenticated +from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.parsers import MultiPartParser @@ -30,6 +30,13 @@ IsInProjectReadOnlyOrAdmin = (IsAnnotatorAndReadOnly | IsAnnotationApproverAndRe IsInProjectOrAdmin = (IsAnnotator | IsAnnotationApprover | IsProjectAdmin) +class Health(APIView): + permission_classes = (IsAuthenticatedOrReadOnly,) + + def get(self, request, *args, **kwargs): + return Response({'status': 'green'}) + + class Me(APIView): permission_classes = (IsAuthenticated,)