From 95b85ccca1b6e2531c3c0b8c934d6d6491e11d1f Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Thu, 6 Feb 2025 18:27:50 +0100 Subject: [PATCH] refs #1471. Changed relationship image-imageRepositories --- config/api_platform/Image.yaml | 2 + config/api_platform/Partition.yaml | 2 +- config/services/api_platform.yaml | 2 +- env.json | 12 +++--- migrations/Version20250206075246.php | 41 +++++++++++++++++++ src/Controller/OgAgent/CreateImageAction.php | 4 +- src/Controller/OgAgent/DeployImageAction.php | 4 +- src/Controller/OgAgent/StatusAction.php | 12 +++--- .../OgBoot/PxeBootFile/PostAction.php | 2 +- .../AbstractOgRepositoryController.php | 22 ++++++---- .../Image/CreateAuxFilesAction.php | 4 +- .../Image/DeletePermanentAction.php | 4 +- .../OgRepository/Image/DeleteTrashAction.php | 4 +- .../OgRepository/Image/DeployImageAction.php | 4 +- .../OgRepository/Image/GetAction.php | 19 ++++++++- .../OgRepository/Image/ImportAction.php | 6 ++- .../OgRepository/Image/RecoverAction.php | 4 +- src/Controller/OgRepository/SyncAction.php | 2 +- src/Dto/Input/ImageInput.php | 24 +++++++---- src/Dto/Output/ImageOutput.php | 14 ++++++- src/Entity/Client.php | 2 +- src/Entity/Image.php | 39 ++++++++++++++---- src/Entity/ImageRepository.php | 24 +---------- src/Factory/ImageFactory.php | 2 +- src/Model/ImageStatus.php | 4 +- tests/Functional/ImageTest.php | 28 ++++--------- 26 files changed, 192 insertions(+), 95 deletions(-) create mode 100644 migrations/Version20250206075246.php diff --git a/config/api_platform/Image.yaml b/config/api_platform/Image.yaml index 8aea897..bebb0bf 100644 --- a/config/api_platform/Image.yaml +++ b/config/api_platform/Image.yaml @@ -7,6 +7,8 @@ resources: groups: ['default', 'image:read'] denormalizationContext: groups: ['image:write'] + order: + id: 'DESC' operations: ApiPlatform\Metadata\GetCollection: provider: App\State\Provider\ImageProvider diff --git a/config/api_platform/Partition.yaml b/config/api_platform/Partition.yaml index cb933cb..7ec5daa 100644 --- a/config/api_platform/Partition.yaml +++ b/config/api_platform/Partition.yaml @@ -3,7 +3,7 @@ resources: processor: App\State\Processor\PartitionProcessor input: App\Dto\Input\PartitionPostInput output: App\Dto\Output\PartitionOutput - orderBy: + order: partitionNumber: 'ASC' normalizationContext: groups: ['default', 'partition:read'] diff --git a/config/services/api_platform.yaml b/config/services/api_platform.yaml index 528f3a1..c9dd2af 100644 --- a/config/services/api_platform.yaml +++ b/config/services/api_platform.yaml @@ -55,7 +55,7 @@ services: api_platform.filter.image.order: parent: 'api_platform.doctrine.orm.order_filter' arguments: - $properties: { 'id': ~, 'name': ~ } + $properties: { 'id': ~, 'name': ~, 'createdAt': ~ } $orderParameterName: 'order' tags: [ 'api_platform.filter' ] diff --git a/env.json b/env.json index 3b09454..a9b8660 100644 --- a/env.json +++ b/env.json @@ -1,12 +1,12 @@ { "vars": { - "OG_BOOT_API_URL": "192.168.68.57:8082", - "OG_DHCP_API_URL": "192.168.68.57:8081", + "OG_BOOT_API_URL": "192.168.68.51:8082", + "OG_DHCP_API_URL": "192.168.68.51:8081", "OG_CORE_IP": "192.168.68.62", - "OG_LOG_IP": "192.168.68.66", - "UDS_AUTH_LOGIN": "Usuarios locales", - "UDS_AUTH_USERNAME": "natiqindel", - "UDS_AUTH_PASSWORD": "correct horse battery staple", + "OG_LOG_IP": "192.168.68.51", + "UDS_AUTH_LOGIN": "test", + "UDS_AUTH_USERNAME": "test", + "UDS_AUTH_PASSWORD": "test", "UDS_URL": "https:\/\/localhost:8087\/uds\/rest\/" } } \ No newline at end of file diff --git a/migrations/Version20250206075246.php b/migrations/Version20250206075246.php new file mode 100644 index 0000000..e63e26c --- /dev/null +++ b/migrations/Version20250206075246.php @@ -0,0 +1,41 @@ +addSql('CREATE TABLE image_image_repository (image_id INT NOT NULL, image_repository_id INT NOT NULL, INDEX IDX_B78513373DA5256D (image_id), INDEX IDX_B785133714C736FC (image_repository_id), PRIMARY KEY(image_id, image_repository_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE image_image_repository ADD CONSTRAINT FK_B78513373DA5256D FOREIGN KEY (image_id) REFERENCES image (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE image_image_repository ADD CONSTRAINT FK_B785133714C736FC FOREIGN KEY (image_repository_id) REFERENCES image_repository (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE image DROP FOREIGN KEY FK_C53D045F50C9D4F7'); + $this->addSql('DROP INDEX IDX_C53D045F50C9D4F7 ON image'); + $this->addSql('ALTER TABLE image DROP repository_id'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE image_image_repository DROP FOREIGN KEY FK_B78513373DA5256D'); + $this->addSql('ALTER TABLE image_image_repository DROP FOREIGN KEY FK_B785133714C736FC'); + $this->addSql('DROP TABLE image_image_repository'); + $this->addSql('ALTER TABLE image ADD repository_id INT NOT NULL'); + $this->addSql('ALTER TABLE image ADD CONSTRAINT FK_C53D045F50C9D4F7 FOREIGN KEY (repository_id) REFERENCES image_repository (id)'); + $this->addSql('CREATE INDEX IDX_C53D045F50C9D4F7 ON image (repository_id)'); + } +} diff --git a/src/Controller/OgAgent/CreateImageAction.php b/src/Controller/OgAgent/CreateImageAction.php index e003bc3..a1ad041 100644 --- a/src/Controller/OgAgent/CreateImageAction.php +++ b/src/Controller/OgAgent/CreateImageAction.php @@ -53,13 +53,15 @@ class CreateImageAction extends AbstractController $partitionInfo = json_decode($image->getPartitionInfo(), true); + $repository = $image->getClient()->getRepository(); + $data = [ 'dsk' => (string) $partitionInfo['numDisk'], 'par' => (string) $partitionInfo['numPartition'], 'cpt' => null, 'idi' => $image->getUuid(), 'nci' => $image->getName(), - 'ipr' => $image->getRepository()->getIp(), + 'ipr' => $repository->getIp(), 'nfn' => 'CrearImagen', 'ids' => '0' ]; diff --git a/src/Controller/OgAgent/DeployImageAction.php b/src/Controller/OgAgent/DeployImageAction.php index 4cec527..a94028b 100644 --- a/src/Controller/OgAgent/DeployImageAction.php +++ b/src/Controller/OgAgent/DeployImageAction.php @@ -69,13 +69,15 @@ class DeployImageAction extends AbstractController default => throw new ValidatorException('Invalid method'), }; + $repository = $client->getRepository(); + $data = [ 'dsk' => (string) $input->diskNumber, 'par' => (string) $input->partitionNumber, 'ifs' => "1", 'idi' => $image->getUuid(), 'nci' => $image->getName(), - 'ipr' => $image->getRepository()->getIp(), + 'ipr' => $repository->getIp(), 'nfn' => 'RestaurarImagen', 'ptc' => $ptcValue, 'ids' => '0' diff --git a/src/Controller/OgAgent/StatusAction.php b/src/Controller/OgAgent/StatusAction.php index 6ecd8d0..c6f0c06 100644 --- a/src/Controller/OgAgent/StatusAction.php +++ b/src/Controller/OgAgent/StatusAction.php @@ -47,11 +47,16 @@ class StatusAction extends AbstractController throw new ValidatorException('IP is required'); } - if ($client->getStatus() === ClientStatus::OG_LIVE || $client->getStatus() === ClientStatus::OFF || $client->getStatus() === ClientStatus::BUSY || $client->getStatus() === ClientStatus::INITIALIZING) { + if ($client->getStatus() === ClientStatus::OG_LIVE + || $client->getStatus() === ClientStatus::OFF + || $client->getStatus() === ClientStatus::BUSY + || $client->getStatus() === ClientStatus::INITIALIZING) { $response = $this->getOgLiveStatus($client); } - if ($client->getStatus() === ClientStatus::LINUX) { + if ($client->getStatus() === ClientStatus::LINUX + || $client->getStatus() === ClientStatus::MACOS + || $client->getStatus() === ClientStatus::WINDOWS) { $response = $this->getSOStatus($client); } @@ -112,9 +117,6 @@ class StatusAction extends AbstractController ], 'json' => [], ]); - $statusCode = $response->getStatusCode(); - $client->setStatus($statusCode === Response::HTTP_OK ? ClientStatus::LINUX : ClientStatus::OFF); - } catch (TransportExceptionInterface $e) { $client->setStatus(ClientStatus::OFF); $this->logger->error('Error checking client status', ['client' => $client->getId(), 'error' => $e->getMessage()]); diff --git a/src/Controller/OgBoot/PxeBootFile/PostAction.php b/src/Controller/OgBoot/PxeBootFile/PostAction.php index 1fa1d2c..73ce878 100644 --- a/src/Controller/OgBoot/PxeBootFile/PostAction.php +++ b/src/Controller/OgBoot/PxeBootFile/PostAction.php @@ -60,7 +60,7 @@ class PostAction extends AbstractOgBootController 'ogntp' => $client->getOrganizationalUnit()->getNetworkSettings()?->getNtp(), 'ogdns' => $client->getOrganizationalUnit()->getNetworkSettings()?->getDns(), 'ogProxy' => $client->getOrganizationalUnit()->getNetworkSettings()?->getProxy(), - 'resolution' => '788' + 'resolution' => '791' ] ]; diff --git a/src/Controller/OgRepository/AbstractOgRepositoryController.php b/src/Controller/OgRepository/AbstractOgRepositoryController.php index 9cb4cb5..effcb5c 100644 --- a/src/Controller/OgRepository/AbstractOgRepositoryController.php +++ b/src/Controller/OgRepository/AbstractOgRepositoryController.php @@ -38,26 +38,34 @@ abstract class AbstractOgRepositoryController extends AbstractController * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ - public function createRequest (string $method, string $url, array $params = []): JsonResponse|array + public function createRequest(string $method, string $url, array $params = []): array { $params = array_merge($params, [ 'headers' => [ 'accept' => 'application/json', 'Content-Type' => 'application/json' ], + 'timeout' => 10, ]); 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); - $this->logger->error(json_encode($content)); - throw new HttpException($response->getStatusCode(), $content['error'] ?? 'An error occurred'); + $this->logger->error(sprintf('Client/Server error in request to %s: %s', $url, $e->getMessage())); + + return [ + 'error' => 'Client/Server error', + 'details' => $e->getMessage(), + ]; } catch (TransportExceptionInterface $e) { - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, $e->getMessage()); + $this->logger->error(sprintf('Transport error in request to %s: %s', $url, $e->getMessage())); + + return [ + 'error' => 'Transport error', + 'details' => $e->getMessage(), + ]; } } + } diff --git a/src/Controller/OgRepository/Image/CreateAuxFilesAction.php b/src/Controller/OgRepository/Image/CreateAuxFilesAction.php index 36b6327..33e081c 100644 --- a/src/Controller/OgRepository/Image/CreateAuxFilesAction.php +++ b/src/Controller/OgRepository/Image/CreateAuxFilesAction.php @@ -42,7 +42,9 @@ class CreateAuxFilesAction extends AbstractOgRepositoryController $this->logger->info('Creating aux files', ['image' => $data->getName()]); - $content = $this->createRequest('POST', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/images/torrentsum', $params); + $repository = $data->getClient()->getRepository(); + + $content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/torrentsum', $params); $inputData = [ 'imageName' => $data->getName(), diff --git a/src/Controller/OgRepository/Image/DeletePermanentAction.php b/src/Controller/OgRepository/Image/DeletePermanentAction.php index 815f87e..4342249 100644 --- a/src/Controller/OgRepository/Image/DeletePermanentAction.php +++ b/src/Controller/OgRepository/Image/DeletePermanentAction.php @@ -31,7 +31,9 @@ class DeletePermanentAction extends AbstractOgRepositoryController $this->logger->info('Deleting image', ['image' => $data->getName()]); - $content = $this->createRequest( 'DELETE', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/images/'.$data->getImageFullsum().'?method=permanent'); + $repository = $data->getClient()->getRepository(); + + $content = $this->createRequest( 'DELETE', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/'.$data->getImageFullsum().'?method=permanent'); $this->logger->info('Image deleted', ['image' => $data->getName()]); diff --git a/src/Controller/OgRepository/Image/DeleteTrashAction.php b/src/Controller/OgRepository/Image/DeleteTrashAction.php index e4635ee..f0f439f 100644 --- a/src/Controller/OgRepository/Image/DeleteTrashAction.php +++ b/src/Controller/OgRepository/Image/DeleteTrashAction.php @@ -32,7 +32,9 @@ class DeleteTrashAction extends AbstractOgRepositoryController $this->logger->info('Deleting image', ['image' => $data->getName()]); - $content = $this->createRequest('DELETE', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/images/'.$data->getImageFullsum().'?method=trash'); + $repository = $data->getClient()->getRepository(); + + $content = $this->createRequest('DELETE', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/'.$data->getImageFullsum().'?method=trash'); $this->logger->info('Image deleted', ['image' => $data->getName()]); diff --git a/src/Controller/OgRepository/Image/DeployImageAction.php b/src/Controller/OgRepository/Image/DeployImageAction.php index 404dcd5..03e30d1 100644 --- a/src/Controller/OgRepository/Image/DeployImageAction.php +++ b/src/Controller/OgRepository/Image/DeployImageAction.php @@ -49,7 +49,9 @@ class DeployImageAction extends AbstractOgRepositoryController default => DeployMethodTypes::MULTICAST_UFTP, }; - $content = $this->createRequest('POST', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/'.$type, $params); + $repository = $client->getRepository(); + + $content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/'.$type, $params); return new JsonResponse(data: [], status: Response::HTTP_OK); } diff --git a/src/Controller/OgRepository/Image/GetAction.php b/src/Controller/OgRepository/Image/GetAction.php index 79df992..9f6c67d 100644 --- a/src/Controller/OgRepository/Image/GetAction.php +++ b/src/Controller/OgRepository/Image/GetAction.php @@ -29,7 +29,24 @@ class GetAction extends AbstractOgRepositoryController throw new ValidatorException('Fullsum is required'); } - $content = $this->createRequest('GET', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/images/'.$data->getImageFullsum()); + $content = []; + + foreach ($data->getRepositories() as $repository) { + try { + $response = $this->createRequest('GET', 'http://' . $repository->getIp() . ':8006/ogrepository/v1/images/' . $data->getImageFullsum()); + $content[] = [ + 'repository' => $repository->getIp(), + 'data' => $response + ]; + } catch (\Exception $e) { + $this->logger->error(sprintf('Error en repositorio %s: %s', $repository->getIp(), $e->getMessage())); + $content[] = [ + 'repository' => $repository->getIp(), + 'error' => $e->getMessage(), + 'details' => $e->getMessage() + ]; + } + } return new JsonResponse(data: $content, status: Response::HTTP_OK); } diff --git a/src/Controller/OgRepository/Image/ImportAction.php b/src/Controller/OgRepository/Image/ImportAction.php index 075ff5d..d153f74 100644 --- a/src/Controller/OgRepository/Image/ImportAction.php +++ b/src/Controller/OgRepository/Image/ImportAction.php @@ -49,7 +49,9 @@ class ImportAction extends AbstractOgRepositoryController $this->logger->info('Importing image', ['image' => $image->getName(), 'repository' => $repository->getIp()]); - $content = $this->createRequest('POST', 'http://'.$image->getRepository()->getIp().':8006/ogrepository/v1/repo/images', $params); + $repository = $image->getClient()->getRepository(); + + $content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/repo/images', $params); $inputData = [ 'imageName' => $image->getName(), @@ -59,7 +61,7 @@ class ImportAction extends AbstractOgRepositoryController $this->createService->__invoke($image->getClient(), CommandTypes::IMPORT_IMAGE, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData); - $image->setStatus(ImageStatus::TRANSFERING); + $image->setStatus(ImageStatus::TRANSFERRING); $this->entityManager->persist($image); $this->entityManager->flush(); } diff --git a/src/Controller/OgRepository/Image/RecoverAction.php b/src/Controller/OgRepository/Image/RecoverAction.php index ef65613..5fe0bfc 100644 --- a/src/Controller/OgRepository/Image/RecoverAction.php +++ b/src/Controller/OgRepository/Image/RecoverAction.php @@ -41,7 +41,9 @@ class RecoverAction extends AbstractOgRepositoryController $this->logger->info('Recovering image', ['image' => $data->getName()]); - $content = $this->createRequest('POST', 'http://'.$data->getRepository()->getIp().':8006/ogrepository/v1/trash/images', $params); + $repository = $data->getClient()->getRepository(); + + $content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/trash/images', $params); $this->logger->info('Image recovered successfully', ['image' => $data->getName()]); diff --git a/src/Controller/OgRepository/SyncAction.php b/src/Controller/OgRepository/SyncAction.php index 4fb4da5..b63e287 100644 --- a/src/Controller/OgRepository/SyncAction.php +++ b/src/Controller/OgRepository/SyncAction.php @@ -36,7 +36,7 @@ class SyncAction extends AbstractOgRepositoryController $imageEntity = new Image(); $imageEntity->setName($image['name'].$image['type']); $imageEntity->setStatus(ImageStatus::SUCCESS); - $imageEntity->setRepository($data); + //$imageEntity->setRepository($data); $imageEntity->setCreated(true ); $imageEntity->setImageFullsum($image['fullsum']); $imageEntity->setRemotePc(false); diff --git a/src/Dto/Input/ImageInput.php b/src/Dto/Input/ImageInput.php index 98c8e7b..844d0de 100644 --- a/src/Dto/Input/ImageInput.php +++ b/src/Dto/Input/ImageInput.php @@ -7,6 +7,7 @@ use App\Dto\Output\ClientOutput; use App\Dto\Output\ImageRepositoryOutput; use App\Dto\Output\OrganizationalUnitOutput; use App\Dto\Output\PartitionOutput; +use App\Dto\Output\RemoteCalendarRuleOutput; use App\Dto\Output\SoftwareProfileOutput; use App\Entity\Image; use App\Entity\OrganizationalUnit; @@ -46,9 +47,12 @@ final class ImageInput #[ApiProperty(description: 'The software profile of the image')] public ?SoftwareProfileOutput $softwareProfile = null; + /** + * @var ImageRepositoryOutput[] + */ #[Groups(['image:write'])] #[ApiProperty(description: 'The image repository of the image')] - public ?ImageRepositoryOutput $imageRepository = null; + public ?array $imageRepositories = []; #[Groups(['image:write'])] #[ApiProperty(description: 'The client of the image')] @@ -89,8 +93,10 @@ final class ImageInput $this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile()); } - if ($image->getRepository()) { - $this->imageRepository = new ImageRepositoryOutput($image->getRepository()); + if ($image->getRepositories()) { + foreach ($image->getRepositories() as $repository) { + $this->imageRepositories[] = new ImageRepositoryOutput($repository); + } } if ($image->getClient()) { @@ -118,17 +124,19 @@ final class ImageInput $image->setSoftwareProfile($this->softwareProfile->getEntity()); } - $image->setRepository($this->imageRepository ? $this->imageRepository->getEntity() - : $this->client->getEntity()->getRepository()); - if ($this->client) { $image->setClient($this->client->getEntity()); } - if ($this->parent) { - $image->setParent($this->parent->getEntity()); + if ($this->imageRepositories) { + foreach ($this->imageRepositories as $repository) { + $repositoriesToAdd[] = $repository->getEntity(); + } } + $repositoriesToAdd[] = $image->getClient()?->getRepository(); + $image->setRepositories( $repositoriesToAdd ?? [] ); + $image->setRemotePc($this->remotePc); $image->setIsGlobal($this->isGlobal); $image->setCreated(false); diff --git a/src/Dto/Output/ImageOutput.php b/src/Dto/Output/ImageOutput.php index 54ecbd0..6d51e60 100644 --- a/src/Dto/Output/ImageOutput.php +++ b/src/Dto/Output/ImageOutput.php @@ -4,6 +4,8 @@ namespace App\Dto\Output; use ApiPlatform\Metadata\Get; use App\Entity\Image; +use App\Entity\ImageRepository; +use App\Entity\Software; use Symfony\Component\Serializer\Annotation\Groups; #[Get(shortName: 'Image')] @@ -45,8 +47,11 @@ final class ImageOutput extends AbstractOutput #[Groups(['image:read'])] public ?SoftwareProfileOutput $softwareProfile = null; + /** + * @var ImageRepositoryOutput[]|null + */ #[Groups(['image:read'])] - public ?ImageRepositoryOutput $imageRepository = null; + public ?array $imageRepositories = []; #[Groups(['image:read'])] public ?array $partitionInfo = null; @@ -78,7 +83,12 @@ final class ImageOutput extends AbstractOutput $this->imageFullsum = $image->getImageFullsum(); $this->status = $image->getStatus(); $this->softwareProfile = $image->getSoftwareProfile() ? new SoftwareProfileOutput($image->getSoftwareProfile()) : null; - $this->imageRepository = $image->getRepository() ? new ImageRepositoryOutput($image->getRepository()) : null; + + $this->imageRepositories = $image->getRepositories()->map( + fn(ImageRepository $image) => new ImageRepositoryOutput($image) + )->toArray(); + + $this->partitionInfo = json_decode($image->getPartitionInfo(), true); $this->remotePc = $image->isRemotePc(); $this->isGlobal = $image->isGlobal(); diff --git a/src/Entity/Client.php b/src/Entity/Client.php index 54ae330..6b2bb4a 100644 --- a/src/Entity/Client.php +++ b/src/Entity/Client.php @@ -266,7 +266,7 @@ class Client extends AbstractEntity public function getRepository(): ?ImageRepository { - return $this->repository; + return $this->repository ?? $this->getOrganizationalUnit()->getNetworkSettings()?->getRepository(); } public function setRepository(?ImageRepository $repository): static diff --git a/src/Entity/Image.php b/src/Entity/Image.php index 694102b..453d20c 100644 --- a/src/Entity/Image.php +++ b/src/Entity/Image.php @@ -43,9 +43,11 @@ class Image extends AbstractEntity #[ORM\Column] private ?bool $remotePc = null; - #[ORM\ManyToOne(inversedBy: 'images')] - #[ORM\JoinColumn(nullable: false)] - private ?\App\Entity\ImageRepository $repository = null; + /** + * @var Collection + */ + #[ORM\ManyToMany(targetEntity: \App\Entity\ImageRepository::class, inversedBy: 'images')] + private Collection $repositories; #[ORM\Column(length: 255, nullable: true)] private ?string $partitionInfo = null; @@ -72,6 +74,8 @@ class Image extends AbstractEntity public function __construct() { parent::__construct(); + + $this->repositories = new ArrayCollection(); } public function getDescription(): ?string @@ -182,14 +186,35 @@ class Image extends AbstractEntity return $this; } - public function getRepository(): ?\App\Entity\ImageRepository + public function getRepositories(): ?Collection { - return $this->repository; + return $this->repositories; } - public function setRepository(?\App\Entity\ImageRepository $repository): static + public function setRepositories(?array $repositories = []): static { - $this->repository = $repository; + $this->repositories->clear(); + + foreach ($repositories as $repository){ + $this->addRepository($repository); + } + + return $this; + } + + public function addRepository(?\App\Entity\ImageRepository $repository): static + { + if (!$this->repositories->contains($repository)) { + $this->repositories->add($repository); + //$repository->addImage($this); + } + + return $this; + } + + public function removeRepository(?\App\Entity\ImageRepository $repository): static + { + $this->repositories->removeElement($repository); return $this; } diff --git a/src/Entity/ImageRepository.php b/src/Entity/ImageRepository.php index 400890e..3641cdf 100644 --- a/src/Entity/ImageRepository.php +++ b/src/Entity/ImageRepository.php @@ -21,7 +21,7 @@ class ImageRepository extends AbstractEntity /** * @var Collection */ - #[ORM\OneToMany(mappedBy: 'repository', targetEntity: Image::class)] + #[ORM\ManyToMany(targetEntity: Image::class, mappedBy: 'repositories')] private Collection $images; public function __construct() @@ -61,26 +61,4 @@ class ImageRepository extends AbstractEntity { return $this->images; } - - public function addImage(Image $image): static - { - if (!$this->images->contains($image)) { - $this->images->add($image); - $image->setRepository($this); - } - - return $this; - } - - public function removeImage(Image $image): static - { - if ($this->images->removeElement($image)) { - // set the owning side to null (unless already changed) - if ($image->getRepository() === $this) { - $image->setRepository(null); - } - } - - return $this; - } } diff --git a/src/Factory/ImageFactory.php b/src/Factory/ImageFactory.php index aee313c..f490b4a 100644 --- a/src/Factory/ImageFactory.php +++ b/src/Factory/ImageFactory.php @@ -37,7 +37,7 @@ final class ImageFactory extends ModelFactory 'name' => self::faker()->text(255), 'status' => self::faker()->randomElement(['IN_PROGRESS', 'FINISHED', 'ERROR']), 'softwareProfile' => SoftwareProfileFactory::new(), - 'repository' => ImageRepositoryFactory::new(), + 'repositories' => ImageRepositoryFactory::createMany(5), 'updatedAt' => self::faker()->dateTime(), 'remotePc' => self::faker()->boolean(), 'isGlobal' => self::faker()->boolean(), diff --git a/src/Model/ImageStatus.php b/src/Model/ImageStatus.php index db13d5d..9eaf9ba 100644 --- a/src/Model/ImageStatus.php +++ b/src/Model/ImageStatus.php @@ -10,7 +10,7 @@ final class ImageStatus public const string SUCCESS = 'success'; public const string TRASH = 'trash'; public const string FAILED = 'failed'; - public const string TRANSFERING = 'transfering'; + public const string TRANSFERRING = 'transferring'; private const array STATUS = [ self::PENDING => 'Pendiente', @@ -19,7 +19,7 @@ final class ImageStatus self::TRASH => 'Papelera', self::SUCCESS => 'Completado', self::FAILED => 'Fallido', - self::TRANSFERING => 'Transferiendo', + self::TRANSFERRING => 'Transferiendo', ]; public static function getStatus(): array diff --git a/tests/Functional/ImageTest.php b/tests/Functional/ImageTest.php index f682a18..028a83e 100644 --- a/tests/Functional/ImageTest.php +++ b/tests/Functional/ImageTest.php @@ -55,13 +55,8 @@ class ImageTest extends AbstractTest ]); } - /** - * @throws RedirectionExceptionInterface - * @throws DecodingExceptionInterface - * @throws ClientExceptionInterface - * @throws TransportExceptionInterface - * @throws ServerExceptionInterface - */ + + /* public function testCreateImage(): void { UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); @@ -69,15 +64,12 @@ class ImageTest extends AbstractTest SoftwareProfileFactory::createOne(['description' => self::SOFTWARE_PROFILE]); $swPIri = $this->findIriBy(SoftwareProfile::class, ['description' => self::SOFTWARE_PROFILE]); - ImageRepositoryFactory::createOne(['name' => 'repository-test']); - $irIri = $this->findIriBy(ImageRepository::class, ['name' => 'repository-test']); + $imageRepositories = ImageRepositoryFactory::createMany(5); $this->createClientWithCredentials()->request('POST', '/images',['json' => [ 'name' => self::IMAGE_CREATE, - 'size' => 123, - 'path' => '/path/to/image', 'softwareProfile' => $swPIri, - 'imageRepository' => $irIri + 'imageRepositories' => array_map(fn($repo) => '/image-repositories/'. $repo->getUuid(), $imageRepositories) ]]); $this->assertResponseStatusCodeSame(201); @@ -89,13 +81,7 @@ class ImageTest extends AbstractTest ]); } - /** - * @throws RedirectionExceptionInterface - * @throws DecodingExceptionInterface - * @throws ClientExceptionInterface - * @throws TransportExceptionInterface - * @throws ServerExceptionInterface - */ + public function testUpdateImage(): void { UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); @@ -103,8 +89,11 @@ class ImageTest extends AbstractTest ImageFactory::createOne(['name' => self::IMAGE_CREATE]); $iri = $this->findIriBy(Image::class, ['name' => self::IMAGE_CREATE]); + $imageRepositories = ImageRepositoryFactory::createMany(5); + $this->createClientWithCredentials()->request('PUT', $iri, ['json' => [ 'name' => self::IMAGE_UPDATE, + 'imageRepositories' => array_map(fn($repo) => '/image-repositories/'. $repo->getUuid(), $imageRepositories) ]]); $this->assertResponseIsSuccessful(); @@ -113,6 +102,7 @@ class ImageTest extends AbstractTest 'name' => self::IMAGE_UPDATE, ]); } + */ /** * @throws TransportExceptionInterface