feat: export state corp package from backup endpoint
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
"""API views экспорта защищённых backup архивов."""
|
||||
|
||||
from apps.backups.serializers import BackupExportRequestSerializer
|
||||
from apps.backups.services import BackupExportError, BackupExportJobService
|
||||
from apps.core.openapi import CommonResponses, ErrorResponses, swagger_tag
|
||||
from apps.exchange.state_corp_services import (
|
||||
StateCorpExchangeError,
|
||||
StateCorpExchangeService,
|
||||
)
|
||||
from django.http import HttpResponse
|
||||
from django.utils import timezone
|
||||
from drf_yasg import openapi
|
||||
@@ -10,14 +13,13 @@ from drf_yasg.utils import swagger_auto_schema
|
||||
from rest_framework import status
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
BACKUPS_TAG = swagger_tag("Резервные копии", "backups")
|
||||
|
||||
|
||||
class BackupExportView(APIView):
|
||||
"""Асинхронный экспорт защищённого backup архива."""
|
||||
"""Синхронный экспорт защищённого ZIP-пакета для state-corp."""
|
||||
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
@@ -25,16 +27,12 @@ class BackupExportView(APIView):
|
||||
tags=[BACKUPS_TAG],
|
||||
operation_summary="Сформировать backup архив",
|
||||
operation_description=(
|
||||
"Асинхронное формирование архива `.zip` на дату актуальности.\n"
|
||||
"Логика endpoint:\n"
|
||||
"- если задача на дату уже выполняется: вернуть 'подождите'\n"
|
||||
"- если задачи нет: запустить формирование\n"
|
||||
"- если задача завершена успешно: отдать архив и удалить его\n\n"
|
||||
"Синхронное формирование архива `.zip` на дату актуальности.\n"
|
||||
"Внутри архива:\n"
|
||||
"- бинарный зашифрованный backup `.bin`\n"
|
||||
"- бинарный зашифрованный пакет `.bin`\n"
|
||||
"- контрольная сумма `.sha256`\n\n"
|
||||
"Экспортирует только актуальные организации из реестров на указанную дату "
|
||||
"и все связанные записи из parser-таблиц."
|
||||
"Экспортирует организации из реестров Росатом и Роскосмос на указанную "
|
||||
"дату и связанные записи из parser-таблиц в контракте импорта state-corp."
|
||||
),
|
||||
request_body=BackupExportRequestSerializer,
|
||||
responses={
|
||||
@@ -42,21 +40,6 @@ class BackupExportView(APIView):
|
||||
description="Готовый backup-архив (application/zip)",
|
||||
schema=openapi.Schema(type=openapi.TYPE_FILE),
|
||||
),
|
||||
202: openapi.Response(
|
||||
description="Задача запущена или выполняется",
|
||||
schema=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
"status": openapi.Schema(type=openapi.TYPE_STRING),
|
||||
"message": openapi.Schema(type=openapi.TYPE_STRING),
|
||||
"actual_date": openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
format=openapi.FORMAT_DATE,
|
||||
),
|
||||
"task_id": openapi.Schema(type=openapi.TYPE_STRING),
|
||||
},
|
||||
),
|
||||
),
|
||||
400: CommonResponses.BAD_REQUEST,
|
||||
**ErrorResponses.ADMIN,
|
||||
},
|
||||
@@ -69,40 +52,23 @@ class BackupExportView(APIView):
|
||||
)
|
||||
|
||||
try:
|
||||
result = BackupExportJobService.check_or_start_job(
|
||||
actual_date=actual_date,
|
||||
requested_by_id=request.user.id
|
||||
if request.user.is_authenticated
|
||||
else None,
|
||||
)
|
||||
except BackupExportError as exc:
|
||||
package = StateCorpExchangeService.build_package(actual_date=actual_date)
|
||||
except StateCorpExchangeError as exc:
|
||||
raise ValidationError({"backup": str(exc)}) from exc
|
||||
|
||||
if result.action in {"started", "wait"}:
|
||||
return Response(
|
||||
{
|
||||
"status": result.action,
|
||||
"message": result.message,
|
||||
"actual_date": result.actual_date.isoformat(),
|
||||
"task_id": result.task_id,
|
||||
},
|
||||
status=status.HTTP_202_ACCEPTED,
|
||||
)
|
||||
|
||||
try:
|
||||
artifact = BackupExportJobService.consume_ready_archive(
|
||||
actual_date=result.actual_date
|
||||
)
|
||||
except BackupExportError as exc:
|
||||
raise ValidationError({"backup": str(exc)}) from exc
|
||||
|
||||
response = HttpResponse(artifact.archive_bytes, content_type="application/zip")
|
||||
response = HttpResponse(package.archive_bytes, content_type="application/zip")
|
||||
response.status_code = status.HTTP_200_OK
|
||||
response[
|
||||
"Content-Disposition"
|
||||
] = f'attachment; filename="{artifact.archive_filename}"'
|
||||
response["X-Backup-SHA256"] = artifact.checksum_sha256
|
||||
response["X-Backup-Checksum-File"] = artifact.checksum_filename
|
||||
response["X-Backup-Organizations"] = str(artifact.organizations_count)
|
||||
response["X-Backup-Actual-Date"] = artifact.actual_date.isoformat()
|
||||
] = f'attachment; filename="{package.archive_name}"'
|
||||
response["Content-Length"] = str(len(package.archive_bytes))
|
||||
response["X-State-Corp-Package-Id"] = package.package_id
|
||||
response["X-State-Corp-Bin-File"] = package.bin_name
|
||||
response["X-State-Corp-Organizations"] = str(
|
||||
package.payload_counts.get("organizations", 0)
|
||||
)
|
||||
response["X-Backup-Organizations"] = str(
|
||||
package.payload_counts.get("organizations", 0)
|
||||
)
|
||||
response["X-Backup-Actual-Date"] = actual_date.isoformat()
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user