From e0795743e769939cb4ee18ac530266e3219682f1 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Fri, 15 Nov 2024 09:06:28 +0100 Subject: [PATCH] refs #1151. Integracion ogRepository --- migrations/Version20241108062659.php | 31 ++++++++++ migrations/Version20241111101047.php | 31 ++++++++++ migrations/Version20241113084353.php | 33 +++++++++++ migrations/Version20241114081247.php | 31 ++++++++++ migrations/Version20241115074840.php | 31 ++++++++++ .../AbstractOgRepositoryController.php | 56 ++++++++++++++++++- .../OgRepository/GetCollectionAction.php | 22 ++------ .../Image/CreateAuxFilesAction.php | 54 +++++++++++++++++- .../Image/DeletePermanentAction.php | 35 +++++++++++- .../OgRepository/Image/DeleteTrashAction.php | 6 +- .../OgRepository/Image/DeployImageAction.php | 3 +- .../OgRepository/Image/GetAction.php | 32 ++++++++++- src/Controller/OgRepository/StatusAction.php | 14 +---- src/Controller/OgRepository/SyncAction.php | 12 ++-- .../Webhook/ResponseController.php | 55 +++++++++++++++++- src/Service/OgRepository/StatusService.php | 38 +++++++++++++ 16 files changed, 433 insertions(+), 51 deletions(-) create mode 100644 migrations/Version20241108062659.php create mode 100644 migrations/Version20241111101047.php create mode 100644 migrations/Version20241113084353.php create mode 100644 migrations/Version20241114081247.php create mode 100644 migrations/Version20241115074840.php diff --git a/migrations/Version20241108062659.php b/migrations/Version20241108062659.php new file mode 100644 index 0000000..8d345ea --- /dev/null +++ b/migrations/Version20241108062659.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE image ADD image_fullsum VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE image DROP image_fullsum'); + } +} diff --git a/migrations/Version20241111101047.php b/migrations/Version20241111101047.php new file mode 100644 index 0000000..75b1819 --- /dev/null +++ b/migrations/Version20241111101047.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE image ADD status VARCHAR(255) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE image DROP status'); + } +} diff --git a/migrations/Version20241113084353.php b/migrations/Version20241113084353.php new file mode 100644 index 0000000..7b81205 --- /dev/null +++ b/migrations/Version20241113084353.php @@ -0,0 +1,33 @@ +addSql('ALTER TABLE network_settings ADD og_log VARCHAR(255) DEFAULT NULL, ADD og_share VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE trace ADD input VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE network_settings DROP og_log, DROP og_share'); + $this->addSql('ALTER TABLE trace DROP input'); + } +} diff --git a/migrations/Version20241114081247.php b/migrations/Version20241114081247.php new file mode 100644 index 0000000..65c180c --- /dev/null +++ b/migrations/Version20241114081247.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE trace CHANGE input input JSON DEFAULT NULL COMMENT \'(DC2Type:json)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE trace CHANGE input input VARCHAR(255) DEFAULT NULL'); + } +} diff --git a/migrations/Version20241115074840.php b/migrations/Version20241115074840.php new file mode 100644 index 0000000..5246bdf --- /dev/null +++ b/migrations/Version20241115074840.php @@ -0,0 +1,31 @@ +addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_NAME ON image (name)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP INDEX UNIQ_IDENTIFIER_NAME ON image'); + } +} diff --git a/src/Controller/OgRepository/AbstractOgRepositoryController.php b/src/Controller/OgRepository/AbstractOgRepositoryController.php index f77270d..0d1f141 100644 --- a/src/Controller/OgRepository/AbstractOgRepositoryController.php +++ b/src/Controller/OgRepository/AbstractOgRepositoryController.php @@ -1,8 +1,58 @@ [ + 'accept' => 'application/json', + 'Content-Type' => 'application/json' + ], + ]); + + try { + $response = $this->httpClient->request($method, $url, $params); + + return json_decode($response->getContent(), true); + } catch (ClientExceptionInterface | ServerExceptionInterface $e) { + $response = $e->getResponse(); + $content = json_decode($response->getContent(false), true); + throw new HttpException($response->getStatusCode(), $content['error'] ?? 'An error occurred'); + } catch (TransportExceptionInterface $e) { + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, $e->getMessage()); + } + } +} diff --git a/src/Controller/OgRepository/GetCollectionAction.php b/src/Controller/OgRepository/GetCollectionAction.php index 74bd7fd..f99bde0 100644 --- a/src/Controller/OgRepository/GetCollectionAction.php +++ b/src/Controller/OgRepository/GetCollectionAction.php @@ -1,10 +1,8 @@ request('GET', $this->ogRepositoryApiUrl.'/ogrepository/v1/images', [ - 'headers' => [ - 'accept' => 'application/json', - ], - ]); - } catch (TransportExceptionInterface $e) { - return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); - } + $content = $this->createRequest($httpClient, 'GET', 'http://'.$data->getIp(). '/ogrepository/v1/images'); - $data = json_decode($response->getContent(), true); - - return new JsonResponse( data: $data, status: Response::HTTP_OK); + return new JsonResponse( data: $content, status: Response::HTTP_OK); } } \ No newline at end of file diff --git a/src/Controller/OgRepository/Image/CreateAuxFilesAction.php b/src/Controller/OgRepository/Image/CreateAuxFilesAction.php index 7ef1b26..199b9da 100644 --- a/src/Controller/OgRepository/Image/CreateAuxFilesAction.php +++ b/src/Controller/OgRepository/Image/CreateAuxFilesAction.php @@ -2,7 +2,57 @@ namespace App\Controller\OgRepository\Image; -class CreateAuxFilesAction -{ +use App\Controller\OgRepository\AbstractOgRepositoryController; +use App\Entity\Command; +use App\Entity\Image; +use App\Model\ImageStatus; +use App\Model\TraceStatus; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\AsController; +use Symfony\Component\Validator\Exception\ValidatorException; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +#[AsController] +class CreateAuxFilesAction extends AbstractOgRepositoryController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(Image $data): JsonResponse + { + if (!$data->getName()) { + throw new ValidatorException('Name is required'); + } + + $params = [ + 'json' => [ + 'image' => $data->getName().'.img' + ] + ]; + + $content = $this->createRequest('POST', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/images/torrentsum', $params); + $command = $this->entityManager->getRepository(Command::class)->findOneBy(['name' => 'Crear Imagen']); + + $inputData = [ + 'imageName' => $data->getName(), + 'imageUuid' => $data->getUuid(), + ]; + + $this->createService->__invoke($data->getClient(), $command, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData); + + $data->setStatus(ImageStatus::IN_PROGRESS); + $this->entityManager->persist($data); + $this->entityManager->flush(); + + return new JsonResponse(data: $content, status: Response::HTTP_OK); + } } \ No newline at end of file diff --git a/src/Controller/OgRepository/Image/DeletePermanentAction.php b/src/Controller/OgRepository/Image/DeletePermanentAction.php index ca82015..e560c6e 100644 --- a/src/Controller/OgRepository/Image/DeletePermanentAction.php +++ b/src/Controller/OgRepository/Image/DeletePermanentAction.php @@ -2,7 +2,38 @@ namespace App\Controller\OgRepository\Image; -class DeletePermanentAction -{ +use App\Controller\OgRepository\AbstractOgRepositoryController; +use App\Entity\Image; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\AsController; +use Symfony\Component\Validator\Exception\ValidatorException; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +#[AsController] +class DeletePermanentAction extends AbstractOgRepositoryController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(Image $data, HttpClientInterface $httpClient): JsonResponse + { + if (!$data->getImageFullsum()) { + throw new ValidatorException('Fullsum is required'); + } + + $content = $this->createRequest($httpClient, 'DELETE', 'http://'.$data->getRepository()->getIp().'/ogrepository/v1/images/'.$data->getImageFullsum().'?method=trash'); + + $this->entityManager->remove($data); + $this->entityManager->flush(); + + return new JsonResponse(data: $content, status: Response::HTTP_OK); + } } \ No newline at end of file diff --git a/src/Controller/OgRepository/Image/DeleteTrashAction.php b/src/Controller/OgRepository/Image/DeleteTrashAction.php index 0fe3b5f..59c671b 100644 --- a/src/Controller/OgRepository/Image/DeleteTrashAction.php +++ b/src/Controller/OgRepository/Image/DeleteTrashAction.php @@ -4,6 +4,7 @@ namespace App\Controller\OgRepository\Image; use App\Controller\OgRepository\AbstractOgRepositoryController; use App\Entity\Image; +use App\Model\ImageStatus; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -15,7 +16,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class DeleteAction extends AbstractOgRepositoryController +class DeleteTrashAction extends AbstractOgRepositoryController { /** * @throws TransportExceptionInterface @@ -31,7 +32,8 @@ class DeleteAction extends AbstractOgRepositoryController $content = $this->createRequest($httpClient, 'DELETE', 'http://'.$data->getRepository()->getIp().'/ogrepository/v1/images/'.$data->getImageFullsum().'?method=trash'); - $this->entityManager->remove($data); + $data->setStatus(ImageStatus::TRASH); + $this->entityManager->persist($data); $this->entityManager->flush(); return new JsonResponse(data: $content, status: Response::HTTP_OK); diff --git a/src/Controller/OgRepository/Image/DeployImageAction.php b/src/Controller/OgRepository/Image/DeployImageAction.php index 3471190..db85293 100644 --- a/src/Controller/OgRepository/Image/DeployImageAction.php +++ b/src/Controller/OgRepository/Image/DeployImageAction.php @@ -8,6 +8,7 @@ use App\Entity\Command; use App\Entity\Image; use App\Model\TraceStatus; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; @@ -16,7 +17,7 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; #[AsController] -class DeployImage extends AbstractOgRepositoryController +class DeployImageAction extends AbstractOgRepositoryController { /** * @throws TransportExceptionInterface diff --git a/src/Controller/OgRepository/Image/GetAction.php b/src/Controller/OgRepository/Image/GetAction.php index 1f35cf5..79df992 100644 --- a/src/Controller/OgRepository/Image/GetAction.php +++ b/src/Controller/OgRepository/Image/GetAction.php @@ -2,7 +2,35 @@ namespace App\Controller\OgRepository\Image; -class GetAction -{ +use App\Controller\OgRepository\AbstractOgRepositoryController; +use App\Entity\Image; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\AsController; +use Symfony\Component\Validator\Exception\ValidatorException; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +#[AsController] +class GetAction extends AbstractOgRepositoryController +{ + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke(Image $data): JsonResponse + { + if (!$data->getImageFullsum()) { + throw new ValidatorException('Fullsum is required'); + } + + $content = $this->createRequest('GET', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/images/'.$data->getImageFullsum()); + + return new JsonResponse(data: $content, status: Response::HTTP_OK); + } } \ No newline at end of file diff --git a/src/Controller/OgRepository/StatusAction.php b/src/Controller/OgRepository/StatusAction.php index 0b6e0e1..74c2654 100644 --- a/src/Controller/OgRepository/StatusAction.php +++ b/src/Controller/OgRepository/StatusAction.php @@ -23,18 +23,8 @@ class StatusAction extends AbstractOgRepositoryController */ public function __invoke(ImageRepository $data, HttpClientInterface $httpClient): JsonResponse { - try { - $response = $httpClient->request('GET', $data->getIp().'/ogrepository/v1/status', [ - 'headers' => [ - 'accept' => 'application/json', - ], - ]); - } catch (TransportExceptionInterface $e) { - return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); - } + $content = $this->createRequest('GET', 'http://'.$data->getIp(). ':8006/ogrepository/v1/status'); - $data = json_decode($response->getContent(), true); - - return new JsonResponse( data: $data, status: Response::HTTP_OK); + return new JsonResponse( data: $content, status: Response::HTTP_OK); } } \ No newline at end of file diff --git a/src/Controller/OgRepository/SyncAction.php b/src/Controller/OgRepository/SyncAction.php index 198c468..957c939 100644 --- a/src/Controller/OgRepository/SyncAction.php +++ b/src/Controller/OgRepository/SyncAction.php @@ -1,17 +1,13 @@ createRequest($httpClient, 'GET', $this->ogRepositoryApiUrl . '/ogrepository/v1/images'); + $content = $this->createRequest($httpClient, 'GET', 'http://'.$data->getIp(). '/ogrepository/v1/images'); if (!isset($content['output']['REPOSITORY']['images'])) { return new JsonResponse(data: 'No images found', status: Response::HTTP_NOT_FOUND); diff --git a/src/Controller/OgRepository/Webhook/ResponseController.php b/src/Controller/OgRepository/Webhook/ResponseController.php index c3d7de3..7a7d0d2 100644 --- a/src/Controller/OgRepository/Webhook/ResponseController.php +++ b/src/Controller/OgRepository/Webhook/ResponseController.php @@ -2,7 +2,58 @@ namespace App\Controller\OgRepository\Webhook; -class ResponseController -{ +use App\Entity\Image; +use App\Entity\Trace; +use App\Model\ImageStatus; +use App\Model\TraceStatus; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Attribute\AsController; +use Symfony\Component\Routing\Annotation\Route; +#[AsController] +class ResponseController extends AbstractController +{ + public function __construct( + protected readonly EntityManagerInterface $entityManager + ) + { + } + + #[Route('/og-repository/webhook', name: 'og_repository_webhook', methods: ['POST'])] + public function repositoryWebhook(Request $request): JsonResponse + { + $data = json_decode($request->getContent(), true); + + $trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]); + $imageUuid = $trace->getInput()['imageUuid']; + + $image = $this->entityManager->getRepository(Image::class)->findOneBy(['uuid' => $imageUuid]); + + if ($image === null) { + $trace->setStatus(TraceStatus::FAILED); + $trace->setFinishedAt(new \DateTime()); + $trace->setOutput('Image not found'); + $this->entityManager->persist($trace); + $this->entityManager->flush(); + + return new JsonResponse(['message' => 'Image not found'], Response::HTTP_NOT_FOUND); + } + + $image->setImageFullsum($data['image_id']); + $image->setStatus(ImageStatus::SUCCESS); + $this->entityManager->persist($image); + + $trace->setStatus(TraceStatus::SUCCESS); + $trace->setFinishedAt(new \DateTime()); + + $this->entityManager->persist($trace); + $this->entityManager->flush(); + + return new JsonResponse($data, Response::HTTP_OK); + + } } \ No newline at end of file diff --git a/src/Service/OgRepository/StatusService.php b/src/Service/OgRepository/StatusService.php index fd9e8ea..248021b 100644 --- a/src/Service/OgRepository/StatusService.php +++ b/src/Service/OgRepository/StatusService.php @@ -2,7 +2,45 @@ namespace App\Service\OgRepository; +use Symfony\Component\HttpClient\HttpClient; +use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + class StatusService { + public function __construct( + ) + { + } + /** + * @throws TransportExceptionInterface + * @throws ServerExceptionInterface + * @throws RedirectionExceptionInterface + * @throws ClientExceptionInterface + */ + public function __invoke() + { + + $httpClient = HttpClient::create([ + 'verify_peer' => false, + 'verify_host' => false, + ]); + + try { + $response = $httpClient->request('GET', ''.'/ogrepository/v1/status', [ + 'headers' => [ + 'accept' => 'application/json', + ], + ]); + } catch (TransportExceptionInterface $e) { + return new JsonResponse( data: 'An error occurred', status: Response::HTTP_INTERNAL_SERVER_ERROR); + } + + return json_decode($response->getContent(), true); + } } \ No newline at end of file