oncall-engine/engine/apps/api/serializers/integration_heartbeat.py
Vadim Stepanov d0904ca405
Improve OpenAPI schema coverage (#3629)
# What this PR does

Improves OpenAPI schema coverage for internal API:

- Fixes/Improves `alert group` and `feature` endpoints
- Adds `integration` and `user` endpoints

## Which issue(s) this PR fixes

https://github.com/grafana/oncall/issues/3444

## Checklist

- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2024-01-12 15:11:22 +00:00

59 lines
2.2 KiB
Python

import humanize
from django.utils import timezone
from rest_framework import serializers
from apps.alerts.models import AlertReceiveChannel
from apps.heartbeat.models import IntegrationHeartBeat
from common.api_helpers.custom_fields import OrganizationFilteredPrimaryKeyRelatedField
from common.api_helpers.mixins import EagerLoadingMixin
class IntegrationHeartBeatSerializer(EagerLoadingMixin, serializers.ModelSerializer):
id = serializers.CharField(read_only=True, source="public_primary_key")
alert_receive_channel = OrganizationFilteredPrimaryKeyRelatedField(queryset=AlertReceiveChannel.objects)
timeout_seconds = serializers.ChoiceField(
allow_null=False,
required=True,
choices=IntegrationHeartBeat.TIMEOUT_CHOICES,
)
last_heartbeat_time_verbal = serializers.SerializerMethodField()
instruction = serializers.SerializerMethodField()
SELECT_RELATED = ["alert_receive_channel"]
class Meta:
model = IntegrationHeartBeat
fields = [
"id",
"timeout_seconds",
"alert_receive_channel",
"link",
"last_heartbeat_time_verbal",
"status",
"instruction",
]
def validate_alert_receive_channel(self, alert_receive_channel):
if alert_receive_channel.is_available_for_integration_heartbeat:
return alert_receive_channel
else:
raise serializers.ValidationError(
{"alert_receive_channel": "Heartbeat is not available for this integration"}
)
def get_last_heartbeat_time_verbal(self, obj) -> str | None:
return self._last_heartbeat_time_verbal(obj) if obj.last_heartbeat_time else None
def get_instruction(self, obj) -> str:
# Deprecated. Kept for API backward compatibility.
return ""
@staticmethod
def _last_heartbeat_time_verbal(instance):
"""
This method simplifies testing.
To compare expected_payload with response.json() it is needed to calculate "now" same way in test and serializer.
It is easier to implement separate method and mock in tests.
"""
now = timezone.now()
return humanize.naturaldelta(now - instance.last_heartbeat_time)