[ApiRouteScope::ID]])] class DumpController { public function __construct( private readonly DumpLister $dumpLister, private readonly DumpService $dumpService, private readonly DumpJobStatusService $jobStatus, private readonly MessageBusInterface $bus, ) { } #[Route( path: '/api/_action/aeon-dump-manager/dumps', name: 'api.action.aeon_dump_manager.dumps.list', defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.viewer']], methods: ['GET'] )] public function list(): JsonResponse { $dumps = array_map( static fn ($dumpFile) => $dumpFile->jsonSerialize(), $this->dumpLister->list() ); return new JsonResponse(['dumps' => $dumps]); } #[Route( path: '/api/_action/aeon-dump-manager/dumps', name: 'api.action.aeon_dump_manager.dumps.create', defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.creator']], methods: ['POST'] )] public function create(): JsonResponse { $jobId = $this->jobStatus->createPending(); $this->bus->dispatch(new CreateDumpMessage($jobId)); return new JsonResponse(['jobId' => $jobId], Response::HTTP_ACCEPTED); } #[Route( path: '/api/_action/aeon-dump-manager/dumps/{filename}', name: 'api.action.aeon_dump_manager.dumps.delete', defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.deleter']], methods: ['DELETE'] )] public function delete(string $filename): JsonResponse { try { $this->dumpService->delete($filename); } catch (DumpNotFoundException $exception) { return new JsonResponse(['message' => $exception->getMessage()], Response::HTTP_NOT_FOUND); } return new JsonResponse(null, Response::HTTP_NO_CONTENT); } #[Route( path: '/api/_action/aeon-dump-manager/dumps/{filename}/download', name: 'api.action.aeon_dump_manager.dumps.download', defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.viewer']], methods: ['GET'] )] public function download(string $filename): StreamedResponse { try { $stream = $this->dumpService->readStream($filename); } catch (DumpNotFoundException $exception) { throw new NotFoundHttpException($exception->getMessage()); } $response = new StreamedResponse(static function () use ($stream): void { fpassthru($stream); }); $response->headers->set('Content-Type', 'application/gzip'); $response->headers->set( 'Content-Disposition', HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $filename) ); return $response; } #[Route( path: '/api/_action/aeon-dump-manager/dumps/jobs/{jobId}', name: 'api.action.aeon_dump_manager.dumps.jobs.status', defaults: [PlatformRequest::ATTRIBUTE_ACL => ['aeon_dump_manager.viewer']], methods: ['GET'] )] public function jobStatus(string $jobId): JsonResponse { $job = $this->jobStatus->find($jobId); if ($job === null) { return new JsonResponse(['message' => 'Job not found'], Response::HTTP_NOT_FOUND); } return new JsonResponse($job); } }