refs #1857. Rename image API integration
testing/ogcore-api/pipeline/head There was a failure building this commit
Details
testing/ogcore-api/pipeline/head There was a failure building this commit
Details
parent
6867f74098
commit
4578f29349
|
@ -64,6 +64,14 @@ resources:
|
|||
uriTemplate: /image-image-repositories/{uuid}/convert-image-to-virtual
|
||||
controller: App\Controller\OgRepository\Image\ConvertImageToVirtualAction
|
||||
|
||||
rename_image_ogrepository:
|
||||
shortName: OgRepository Server
|
||||
class: ApiPlatform\Metadata\Post
|
||||
method: POST
|
||||
input: App\Dto\Input\RenameImageInput
|
||||
uriTemplate: /image-image-repositories/{uuid}/rename-image
|
||||
controller: App\Controller\OgRepository\Image\RenameAction
|
||||
|
||||
trash_delete_image_ogrepository:
|
||||
shortName: OgRepository Server
|
||||
description: Delete Image in OgRepository
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250409093554 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE image_image_repository ADD name 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_image_repository DROP name');
|
||||
}
|
||||
}
|
|
@ -4,8 +4,10 @@ namespace App\Controller\OgRepository\Image;
|
|||
|
||||
use App\Controller\OgRepository\AbstractOgRepositoryController;
|
||||
use App\Dto\Input\DeployImageInput;
|
||||
use App\Dto\Input\RenameImageInput;
|
||||
use App\Entity\Image;
|
||||
use App\Entity\ImageImageRepository;
|
||||
use App\Entity\ImageRepository;
|
||||
use App\Model\CommandTypes;
|
||||
use App\Model\ImageStatus;
|
||||
use App\Model\TraceStatus;
|
||||
|
@ -28,59 +30,96 @@ class RenameAction extends AbstractOgRepositoryController
|
|||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(Image $image): JsonResponse
|
||||
public function __invoke(RenameImageInput $input, ImageImageRepository $imageImageRepository): JsonResponse
|
||||
{
|
||||
$repositories = $image->getImageImageRepositories();
|
||||
$image = $imageImageRepository->getImage();
|
||||
|
||||
if ($repositories->count() === 0) {
|
||||
return new JsonResponse(data: ['error' => 'Image is not in any repository', 'code' => Response::HTTP_INTERNAL_SERVER_ERROR], status: Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
if ($image->isGlobal()) {
|
||||
$repositories = $image->getImageImageRepositories();
|
||||
|
||||
$allGood = true;
|
||||
foreach ($repositories as $repository) {
|
||||
try {
|
||||
$content = $this->createRequest('GET', 'http://'.$repository->getRepository()->getIp(). ':8006/ogrepository/v1/status');
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$allGood = false;
|
||||
break;
|
||||
if ($repositories->count() === 0) {
|
||||
return $this->jsonError('Image is not in any repository');
|
||||
}
|
||||
|
||||
if (!$this->isAvailableInAllRepositories($repositories)) {
|
||||
$this->logger->info('Image is not available in all repositories', ['image' => $image->getName()]);
|
||||
return $this->jsonError('Image is not available in all repositories');
|
||||
}
|
||||
|
||||
$repoWithImage = $this->entityManager
|
||||
->getRepository(ImageImageRepository::class)
|
||||
->findBy(['image' => $image, 'repository' => $imageImageRepository->getRepository()]);
|
||||
} else {
|
||||
$repoWithImage = [$imageImageRepository];
|
||||
}
|
||||
|
||||
if (!$allGood) {
|
||||
$this->logger->info('Image is not available in all repositories', ['image' => $image->getName()]);
|
||||
return new JsonResponse(data: ['error' => 'Image is not available in all repositories', 'code' => Response::HTTP_INTERNAL_SERVER_ERROR], status: Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$image->setVersion($image->getVersion() + 1);
|
||||
$this->entityManager->persist($image);
|
||||
|
||||
$conditional = false;
|
||||
|
||||
$latestImageRepo = $this->entityManager->getRepository(ImageImageRepository::class)->findLatestVersion();
|
||||
$repoWithImage = $this->entityManager->getRepository(ImageImageRepository::class)->findBy(['image' => $image, 'version' => $latestImageRepo->getVersion()]);
|
||||
|
||||
$hasError = false;
|
||||
|
||||
foreach ($repoWithImage as $repository) {
|
||||
$params = [
|
||||
'json' => [
|
||||
'ID_img' => $repository->getImageFullsum(),
|
||||
'image_new_name' => $image->getName().'_v'.$image->getVersion(),
|
||||
]
|
||||
];
|
||||
$content = $this->renameImageInRepository($repository, $input->newName);
|
||||
|
||||
$content = $this->createRequest('PUT', 'http://'.$repository->getRepository()->getIp().':8006/ogrepository/v1/images/rename', $params);
|
||||
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
$conditional = true;
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
$hasError = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($conditional) {
|
||||
return new JsonResponse(data: ['error' => 'Error renaming image'], status: Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$repository->setName($input->newName);
|
||||
$this->entityManager->persist($repository);
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
if ($hasError) {
|
||||
return new JsonResponse(['error' => 'Error renaming image'], Response::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
return new JsonResponse([], Response::HTTP_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
private function isAvailableInAllRepositories($repositories): bool
|
||||
{
|
||||
foreach ($repositories as $repository) {
|
||||
try {
|
||||
$this->createRequest('GET', 'http://' . $repository->getRepository()->getIp() . ':8006/ogrepository/v1/status');
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
private function renameImageInRepository(ImageImageRepository $repository, string $newName): array
|
||||
{
|
||||
$params = [
|
||||
'json' => [
|
||||
'ID_img' => $repository->getImageFullsum(),
|
||||
'image_new_name' => $newName,
|
||||
]
|
||||
];
|
||||
|
||||
return $this->createRequest(
|
||||
'PUT',
|
||||
'http://' . $repository->getRepository()->getIp() . ':8006/ogrepository/v1/images/rename',
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
private function jsonError(string $message): JsonResponse
|
||||
{
|
||||
return new JsonResponse(
|
||||
['error' => $message, 'code' => Response::HTTP_INTERNAL_SERVER_ERROR],
|
||||
Response::HTTP_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Dto\Input;
|
||||
|
||||
use Symfony\Component\Serializer\Annotation\Groups;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
final class RenameImageInput
|
||||
{
|
||||
#[Assert\NotNull]
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
public ?string $newName = '';
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace App\Factory;
|
||||
|
||||
use App\Entity\ImageImageRepository;
|
||||
use App\Repository\ImageImageRepositoryRepository;
|
||||
use Zenstruck\Foundry\ModelFactory;
|
||||
use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory;
|
||||
use Zenstruck\Foundry\Persistence\Proxy;
|
||||
use Zenstruck\Foundry\Persistence\ProxyRepositoryDecorator;
|
||||
|
||||
/**
|
||||
* @extends PersistentProxyObjectFactory<ImageImageRepository>
|
||||
*/
|
||||
final class ImageImageRepositoryFactory extends ModelFactory
|
||||
{
|
||||
/**
|
||||
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
|
||||
*
|
||||
* @todo inject services if required
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
|
||||
*
|
||||
* @todo add your default values here
|
||||
*/
|
||||
protected function getDefaults(): array
|
||||
{
|
||||
return [
|
||||
'createdAt' => self::faker()->dateTime(),
|
||||
'image' => ImageFactory::new(),
|
||||
'name' => self::faker()->text(255),
|
||||
'repository' => ImageRepositoryFactory::new(),
|
||||
'status' => self::faker()->text(255),
|
||||
'updatedAt' => self::faker()->dateTime(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
|
||||
*/
|
||||
protected function initialize(): self
|
||||
{
|
||||
return $this
|
||||
// ->afterInstantiate(function(ImageImageRepository $imageImageRepository): void {})
|
||||
;
|
||||
}
|
||||
|
||||
protected static function getClass(): string
|
||||
{
|
||||
return ImageImageRepository::class;
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ use App\Entity\OrganizationalUnit;
|
|||
use App\Entity\SoftwareProfile;
|
||||
use App\Factory\ClientFactory;
|
||||
use App\Factory\ImageFactory;
|
||||
use App\Factory\ImageImageRepositoryFactory;
|
||||
use App\Factory\ImageRepositoryFactory;
|
||||
use App\Factory\OrganizationalUnitFactory;
|
||||
use App\Factory\SoftwareProfileFactory;
|
||||
|
@ -70,12 +71,12 @@ class ImageTest extends AbstractTest
|
|||
SoftwareProfileFactory::createOne(['description' => self::SOFTWARE_PROFILE]);
|
||||
$swPIri = $this->findIriBy(SoftwareProfile::class, ['description' => self::SOFTWARE_PROFILE]);
|
||||
|
||||
$imageRepositories = ImageRepositoryFactory::createMany(5);
|
||||
$imageRepositories = ImageImageRepositoryFactory::createMany(5);
|
||||
|
||||
$this->createClientWithCredentials()->request('POST', '/images',['json' => [
|
||||
'name' => self::IMAGE_CREATE,
|
||||
'softwareProfile' => $swPIri,
|
||||
'imageRepositories' => array_map(fn($repo) => '/image-repositories/'. $repo->getUuid(), $imageRepositories)
|
||||
'imageImageRepositories' => array_map(fn($repo) => '/image-repositories/'. $repo->getUuid(), $imageRepositories)
|
||||
]]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(201);
|
||||
|
@ -102,11 +103,11 @@ class ImageTest extends AbstractTest
|
|||
ImageFactory::createOne(['name' => self::IMAGE_CREATE]);
|
||||
$iri = $this->findIriBy(Image::class, ['name' => self::IMAGE_CREATE]);
|
||||
|
||||
$imageRepositories = ImageRepositoryFactory::createMany(5);
|
||||
$imageRepositories = ImageImageRepositoryFactory::createMany(5);
|
||||
|
||||
$this->createClientWithCredentials()->request('PUT', $iri, ['json' => [
|
||||
'name' => self::IMAGE_UPDATE,
|
||||
'imageRepositories' => array_map(fn($repo) => '/image-repositories/'. $repo->getUuid(), $imageRepositories)
|
||||
'imageImageRepositories' => array_map(fn($repo) => '/image-repositories/'. $repo->getUuid(), $imageRepositories)
|
||||
]]);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
|
Loading…
Reference in New Issue