refs #1555. Install Mercure
parent
f9feafa9b8
commit
560559bba9
6
.env
6
.env
|
@ -50,3 +50,9 @@ UDS_AUTH_USERNAME="natiqindel"
|
|||
UDS_AUTH_PASSWORD="correct horse battery staple"
|
||||
UDS_URL=https://localhost:8087/uds/rest/
|
||||
###< UDS ###
|
||||
|
||||
###> symfony/mercure-bundle ###
|
||||
MERCURE_URL=http://ogcore-mercure:3000/.well-known/mercure
|
||||
MERCURE_PUBLIC_URL=http://ogcore-mercure:3000/.well-known/mercure
|
||||
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"
|
||||
###< symfony/mercure-bundle ###
|
||||
|
|
|
@ -5,3 +5,9 @@ services:
|
|||
ports:
|
||||
- "5432"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> symfony/mercure-bundle ###
|
||||
mercure:
|
||||
ports:
|
||||
- "80"
|
||||
###< symfony/mercure-bundle ###
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"symfony/flex": "^2",
|
||||
"symfony/framework-bundle": "6.4.*",
|
||||
"symfony/http-client": "6.4.*",
|
||||
"symfony/mercure-bundle": "^0.3.9",
|
||||
"symfony/monolog-bundle": "^3.10",
|
||||
"symfony/property-access": "6.4.*",
|
||||
"symfony/property-info": "6.4.*",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2df97d4a1797242acadb47d83b3fbe98",
|
||||
"content-hash": "ac4764e765324b86e616d7eb47a55e63",
|
||||
"packages": [
|
||||
{
|
||||
"name": "api-platform/core",
|
||||
|
@ -4981,6 +4981,173 @@
|
|||
],
|
||||
"time": "2024-11-27T12:49:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mercure",
|
||||
"version": "v0.6.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mercure.git",
|
||||
"reference": "304cf84609ef645d63adc65fc6250292909a461b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mercure/zipball/304cf84609ef645d63adc65fc6250292909a461b",
|
||||
"reference": "304cf84609ef645d63adc65fc6250292909a461b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"symfony/deprecation-contracts": "^2.0|^3.0|^4.0",
|
||||
"symfony/http-client": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/http-foundation": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/polyfill-php80": "^1.22",
|
||||
"symfony/web-link": "^4.4|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"lcobucci/jwt": "^3.4|^4.0|^5.0",
|
||||
"symfony/event-dispatcher": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/http-kernel": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/phpunit-bridge": "^5.2|^6.0|^7.0",
|
||||
"symfony/stopwatch": "^4.4|^5.0|^6.0|^7.0",
|
||||
"twig/twig": "^2.0|^3.0|^4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/stopwatch": "Integration with the profiler performances"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/dunglas/mercure",
|
||||
"name": "dunglas/mercure"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "0.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Mercure\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kévin Dunglas",
|
||||
"email": "dunglas@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Mercure Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"mercure",
|
||||
"push",
|
||||
"sse",
|
||||
"updates"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/mercure/issues",
|
||||
"source": "https://github.com/symfony/mercure/tree/v0.6.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/dunglas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/mercure",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-08T12:51:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mercure-bundle",
|
||||
"version": "v0.3.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mercure-bundle.git",
|
||||
"reference": "77435d740b228e9f5f3f065b6db564f85f2cdb64"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/77435d740b228e9f5f3f065b6db564f85f2cdb64",
|
||||
"reference": "77435d740b228e9f5f3f065b6db564f85f2cdb64",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"lcobucci/jwt": "^3.4|^4.0|^5.0",
|
||||
"php": ">=7.1.3",
|
||||
"symfony/config": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/dependency-injection": "^4.4|^5.4|^6.0|^7.0",
|
||||
"symfony/http-kernel": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/mercure": "^0.6.1",
|
||||
"symfony/web-link": "^4.4|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.3.7|^5.0|^6.0|^7.0",
|
||||
"symfony/stopwatch": "^4.3.7|^5.0|^6.0|^7.0",
|
||||
"symfony/ux-turbo": "*",
|
||||
"symfony/var-dumper": "^4.3.7|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/messenger": "To use the Messenger integration"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "0.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Bundle\\MercureBundle\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kévin Dunglas",
|
||||
"email": "dunglas@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony MercureBundle",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"mercure",
|
||||
"push",
|
||||
"sse",
|
||||
"updates"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/mercure-bundle/issues",
|
||||
"source": "https://github.com/symfony/mercure-bundle/tree/v0.3.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/dunglas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/mercure-bundle",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-31T09:07:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/monolog-bridge",
|
||||
"version": "v6.4.13",
|
||||
|
|
|
@ -7,6 +7,7 @@ resources:
|
|||
groups: ['default', 'client:read']
|
||||
denormalizationContext:
|
||||
groups: ['client:write']
|
||||
|
||||
operations:
|
||||
ApiPlatform\Metadata\GetCollection:
|
||||
provider: App\State\Provider\ClientProvider
|
||||
|
|
|
@ -17,4 +17,5 @@ return [
|
|||
Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
|
||||
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
|
||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
|
||||
];
|
||||
|
|
|
@ -5,6 +5,9 @@ api_platform:
|
|||
path_segment_name_generator: api_platform.path_segment_name_generator.dash
|
||||
defaults:
|
||||
pagination_client_items_per_page: true
|
||||
mercure:
|
||||
enabled: true
|
||||
|
||||
collection:
|
||||
pagination:
|
||||
items_per_page_parameter_name: 'itemsPerPage'
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
mercure:
|
||||
hubs:
|
||||
default:
|
||||
url: '%env(MERCURE_URL)%'
|
||||
public_url: '%env(MERCURE_PUBLIC_URL)%'
|
||||
jwt:
|
||||
secret: '%env(MERCURE_JWT_SECRET)%'
|
||||
publish: '*'
|
|
@ -20,11 +20,10 @@ when@test:
|
|||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
channels: ["!event"]
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: error
|
||||
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
|
|
|
@ -42,7 +42,31 @@ services:
|
|||
networks:
|
||||
- ogcore-network
|
||||
|
||||
|
||||
mercure:
|
||||
image: dunglas/mercure
|
||||
restart: unless-stopped
|
||||
container_name: ogcore-mercure
|
||||
environment:
|
||||
# Uncomment the following line to disable HTTPS,
|
||||
SERVER_NAME: ':3000'
|
||||
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||
MERCURE_EXTRA_DIRECTIVES: |
|
||||
cors_origins *
|
||||
# Comment the following line to disable the development mode
|
||||
command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- mercure_data:/data
|
||||
- mercure_config:/config
|
||||
networks:
|
||||
- ogcore-network
|
||||
|
||||
volumes:
|
||||
mercure_data:
|
||||
mercure_config:
|
||||
database_data:
|
||||
|
||||
networks:
|
||||
|
|
|
@ -15,6 +15,17 @@ server {
|
|||
ssl_certificate /etc/nginx/certs/ogcore.uds-test.net.crt.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/ogcore.uds-test.net.key.pem;
|
||||
|
||||
location /.well-known/mercure {
|
||||
proxy_pass https://mercure:3000/.well-known/mercure;
|
||||
proxy_read_timeout 24h;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /opengnsys/rest/ous// {
|
||||
rewrite ^/opengnsys/rest/ous//([0-9]+)/images /opengnsys/rest/ous/$1/images;
|
||||
rewrite ^/opengnsys/rest/ous//([0-9]+)/labs /opengnsys/rest/ous/$1/labs;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<server name="SHELL_VERBOSITY" value="-1" />
|
||||
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
|
||||
<server name="SYMFONY_PHPUNIT_VERSION" value="9.6" />
|
||||
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Entity\Client;
|
||||
use App\Entity\Trace;
|
||||
use App\Model\ClientStatus;
|
||||
use App\Model\TraceStatus;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\Mercure\HubInterface;
|
||||
use Symfony\Component\Mercure\Update;
|
||||
|
||||
#[AsCommand(name: 'opengnsys:test', description: 'Hello PhpStorm')]
|
||||
class TestCommand extends Command
|
||||
{
|
||||
public function __construct(
|
||||
private readonly HubInterface $hub,
|
||||
private readonly EntityManagerInterface $entityManager
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->find(7236);
|
||||
|
||||
$trace->setStatus(TraceStatus::SUCCESS);
|
||||
$trace->setProgress(1000);
|
||||
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
|
@ -47,8 +47,6 @@ class DeployImageAction extends AbstractController
|
|||
throw new ValidatorException('IP is required');
|
||||
}
|
||||
|
||||
$partitionInfo = json_decode($image->getPartitionInfo(), true);
|
||||
|
||||
$method = match ($input->method) {
|
||||
DeployMethodTypes::MULTICAST_UFTP_DIRECT, DeployMethodTypes::MULTICAST_UDPCAST_DIRECT, => 'multicast-direct',
|
||||
DeployMethodTypes::MULTICAST, DeployMethodTypes::MULTICAST_UFTP, DeployMethodTypes::MULTICAST_UDPCAST => 'multicast',
|
||||
|
|
|
@ -41,12 +41,17 @@ class PowerOffAction extends AbstractController
|
|||
public function __invoke(MultipleClientsInput $input): JsonResponse
|
||||
{
|
||||
foreach ($input->clients as $clientEntity) {
|
||||
/** @var Client $client */
|
||||
$client = $clientEntity->getEntity();
|
||||
|
||||
if (!$client->getIp()) {
|
||||
throw new ValidatorException('IP is required');
|
||||
}
|
||||
|
||||
if ($client->getStatus() === ClientStatus::OFF) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'nfn' => 'Apagar',
|
||||
'ids' => '0'
|
||||
|
@ -70,7 +75,7 @@ class PowerOffAction extends AbstractController
|
|||
|
||||
$jobId = json_decode($response->getContent(), true)['job_id'];
|
||||
|
||||
$client->setStatus(ClientStatus::OFF);
|
||||
$client->setStatus(ClientStatus::TURNING_OFF);
|
||||
$this->entityManager->persist($client);
|
||||
$this->entityManager->flush();
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|||
#[AsController]
|
||||
class ClientsController extends AbstractController
|
||||
{
|
||||
const string CREATE_IMAGE = 'RESPUESTA_CrearImagen';
|
||||
const string RESTORE_IMAGE = 'RESPUESTA_RestaurarImagen';
|
||||
const string CONFIGURE_IMAGE = 'RESPUESTA_Configurar';
|
||||
|
||||
|
||||
public function __construct(
|
||||
protected readonly EntityManagerInterface $entityManager,
|
||||
public readonly CreateAuxFilesAction $createAuxFilesAction,
|
||||
|
@ -54,7 +59,7 @@ class ClientsController extends AbstractController
|
|||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$data = $request->toArray();
|
||||
$requiredFields = ['nfn', 'res', 'der', 'job_id'];
|
||||
$requiredFields = ['job_id'];
|
||||
|
||||
foreach ($requiredFields as $field) {
|
||||
if (!isset($data[$field])) {
|
||||
|
@ -64,7 +69,16 @@ class ClientsController extends AbstractController
|
|||
|
||||
$this->logger->info('Webhook data received', $data);
|
||||
|
||||
if ($data['nfn'] === 'RESPUESTA_CrearImagen') {
|
||||
if (isset($data['progress'])){
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
if ($trace){
|
||||
$trace->setProgress($data['progress'] * 1000);
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['nfn']) && $data['nfn'] === self::CREATE_IMAGE) {
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
/** @var ImageImageRepository $imageImageRepository */
|
||||
$imageImageRepository = $this->entityManager->getRepository(ImageImageRepository::class)->findOneBy(['uuid' => $data['idi']]);
|
||||
|
@ -82,10 +96,8 @@ class ClientsController extends AbstractController
|
|||
if ($data['res'] === 1) {
|
||||
$trace->setStatus(TraceStatus::SUCCESS);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
|
||||
$imageImageRepository->setStatus(ImageStatus::AUX_FILES_PENDING);
|
||||
$imageImageRepository->setCreated(true);
|
||||
|
||||
$this->entityManager->persist($imageImageRepository);
|
||||
|
||||
$this->logger->info('Start partition creation. ', ['image' => (string) $imageImageRepository->getUuid()]);
|
||||
|
@ -95,11 +107,13 @@ class ClientsController extends AbstractController
|
|||
$this->logger->info('Starting software profile creation. ', ['image' => (string) $imageImageRepository->getUuid()]);
|
||||
$this->createSoftwareProfile($data['inv_sft'], $imageImageRepository);
|
||||
$this->logger->info('Start aux files ogrepo API ', ['image' => (string) $imageImageRepository->getUuid()]);
|
||||
|
||||
try {
|
||||
$this->createAuxFilesAction->__invoke($imageImageRepository);
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error('Error creating aux files', ['image' => (string) $imageImageRepository->getUuid(), 'error' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$this->logger->info('End aux files ogrepo API ', ['image' => (string) $imageImageRepository->getUuid()]);
|
||||
} else {
|
||||
$trace->setStatus(TraceStatus::FAILED);
|
||||
|
@ -119,9 +133,8 @@ class ClientsController extends AbstractController
|
|||
$this->logger->info('Image updated. Success.', ['image' => (string) $imageImageRepository->getUuid()]);
|
||||
}
|
||||
|
||||
if ($data['nfn'] === 'RESPUESTA_RestaurarImagen'|| $data['nfn'] === 'RESPUESTA_Configurar') {
|
||||
if (isset($data['nfn']) && ($data['nfn'] === self::RESTORE_IMAGE || $data['nfn'] === self::CONFIGURE_IMAGE)) {
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
|
||||
$client = $trace->getClient();
|
||||
|
||||
if ($data['res'] === 1) {
|
||||
|
|
|
@ -45,7 +45,7 @@ class CreateAuxFilesAction extends AbstractOgRepositoryController
|
|||
|
||||
$this->logger->info('Creating aux files', ['image' => $image->getName()]);
|
||||
|
||||
$repository = $image->getClient()->getRepository();
|
||||
$repository = $data->getRepository();
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/torrentsum', $params);
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ class DeleteTrashAction extends AbstractOgRepositoryController
|
|||
|
||||
$this->logger->info('Deleting image', ['image' => $image->getName()]);
|
||||
|
||||
$repository = $image->getClient()->getRepository();
|
||||
|
||||
$content = $this->createRequest('DELETE', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/'.$imageImageRepository->getImageFullsum().'?method=trash');
|
||||
|
||||
$this->logger->info('Image deleted', ['image' => $image->getName()]);
|
||||
|
|
|
@ -44,7 +44,7 @@ class RecoverAction extends AbstractOgRepositoryController
|
|||
|
||||
$this->logger->info('Recovering image', ['image' => $image->getName()]);
|
||||
|
||||
$repository = $image->getClient()->getRepository();
|
||||
$repository = $data->getRepository();
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/trash/images', $params);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ final class TraceOutput extends AbstractOutput
|
|||
public ?\DateTimeInterface $finishedAt = null;
|
||||
|
||||
#[Groups(['trace:read'])]
|
||||
public ?int $progress = null;
|
||||
public ?float $progress = null;
|
||||
|
||||
#[Groups(['trace:read'])]
|
||||
public \DateTime $createdAt;
|
||||
|
@ -59,7 +59,7 @@ final class TraceOutput extends AbstractOutput
|
|||
$this->output = $trace->getOutput();
|
||||
$this->input = $trace->getInput();
|
||||
$this->finishedAt = $trace->getFinishedAt();
|
||||
$this->progress = $trace->getProgress();
|
||||
$this->progress = $trace->getProgress() / 100;
|
||||
$this->createdAt = $trace->getCreatedAt();
|
||||
$this->createdBy = $trace->getCreatedBy();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use App\Repository\ClientRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
@ -152,6 +153,7 @@ class Client extends AbstractEntity
|
|||
return $this->status;
|
||||
}
|
||||
|
||||
#[ORM\PostPersist]
|
||||
public function setStatus(?string $status): static
|
||||
{
|
||||
$this->status = $status;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
|
||||
use App\Entity\Client;
|
||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Mercure\HubInterface;
|
||||
use Symfony\Component\Mercure\Update;
|
||||
|
||||
#[AsEntityListener(event: Events::postUpdate, method: 'postUpdate', entity: Client::class)]
|
||||
class ClientStatusNotifier
|
||||
{
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
private readonly HubInterface $hub
|
||||
)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function postUpdate(Client $client, PostUpdateEventArgs $event): void
|
||||
{
|
||||
$update = new Update(
|
||||
'clients',
|
||||
json_encode(['@id' => '/clients/'.$client->getUuid(), 'status' => $client->getStatus()])
|
||||
);
|
||||
$this->hub->publish($update);
|
||||
|
||||
$this->logger->info('Evento Mercure disparado. Cambio en el estado de un cliente: ', [
|
||||
'client' => $client->getUuid(),
|
||||
'status' => $client->getStatus(),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
|
||||
use App\Entity\Client;
|
||||
use App\Entity\Trace;
|
||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Mercure\HubInterface;
|
||||
use Symfony\Component\Mercure\Update;
|
||||
|
||||
#[AsEntityListener(event: Events::postUpdate, method: 'postUpdate', entity: Trace::class)]
|
||||
class TraceStatusProgressNotifier
|
||||
{
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
private readonly HubInterface $hub
|
||||
)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function postUpdate(Trace $trace, PostUpdateEventArgs $event): void
|
||||
{
|
||||
$update = new Update(
|
||||
'traces',
|
||||
json_encode(['@id' => '/traces/'.$trace->getUuid(), 'status' => $trace->getStatus(), 'progress' => $trace->getProgress() / 100])
|
||||
);
|
||||
$this->hub->publish($update);
|
||||
|
||||
$this->logger->info('Evento Mercure disparado. Cambio en el estado de una traza/log: ', [
|
||||
'client' => $trace->getUuid(),
|
||||
'status' => $trace->getStatus(),
|
||||
'progress' => $trace->getProgress(),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\EventSubscriber;
|
||||
|
||||
use ApiPlatform\Symfony\EventListener\EventPriorities;
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Entity\Client;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Event\ViewEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Mercure\HubInterface;
|
||||
use Symfony\Component\Mercure\Update;
|
||||
|
||||
class MercureSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
private readonly HubInterface $hub
|
||||
)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
KernelEvents::VIEW => ['onKernelView', EventPriorities::POST_WRITE],
|
||||
];
|
||||
}
|
||||
|
||||
public function onKernelView(ViewEvent $event): void
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
$method = $request->getMethod();
|
||||
|
||||
$clientOutput = $event->getControllerResult();
|
||||
|
||||
if (!in_array($method, ['POST', 'PUT', 'PATCH', 'DELETE'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$method = $event->getRequest()->getMethod();
|
||||
|
||||
if (!$clientOutput instanceof ClientOutput || (Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method && Request::METHOD_PATCH !== $method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Client $client */
|
||||
$client = $clientOutput->getEntity();
|
||||
|
||||
$update = new Update(
|
||||
'clients',
|
||||
json_encode(['@id' => '/clients/'.$client->getUuid(), 'status' => $client->getStatus()])
|
||||
);
|
||||
$this->hub->publish($update);
|
||||
|
||||
$this->logger->info('Evento Mercure disparado', [
|
||||
'method' => $method,
|
||||
'path' => $request->getPathInfo()
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -5,27 +5,20 @@ namespace App\Model;
|
|||
final class ClientStatus
|
||||
{
|
||||
public const string OFF = 'off';
|
||||
|
||||
public const string INITIALIZING = 'initializing';
|
||||
|
||||
public const string TURNING_OFF = 'turning-off';
|
||||
public const string OG_LIVE = 'og-live';
|
||||
|
||||
public const string BUSY = 'busy';
|
||||
|
||||
public const string LINUX = 'linux';
|
||||
|
||||
public const string LINUX_SESSION = 'linux-session';
|
||||
|
||||
public const string MACOS = 'macos';
|
||||
|
||||
public const string MACOS_SESSION = 'macos-session';
|
||||
|
||||
public const string WINDOWS = 'windows';
|
||||
|
||||
public const string WINDOWS_SESSION = 'windows-session';
|
||||
|
||||
private const array CLIENT_STATUSES = [
|
||||
self::OFF => 'Apagado',
|
||||
self::TURNING_OFF => 'Apagando',
|
||||
self::INITIALIZING => 'Inicializando',
|
||||
self::OG_LIVE => 'OG Live',
|
||||
self::BUSY => 'Ocupado',
|
||||
|
|
99
symfony.lock
99
symfony.lock
|
@ -13,6 +13,18 @@
|
|||
"src/ApiResource/.gitignore"
|
||||
]
|
||||
},
|
||||
"dama/doctrine-test-bundle": {
|
||||
"version": "8.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes-contrib",
|
||||
"branch": "main",
|
||||
"version": "7.2",
|
||||
"ref": "896306d79d4ee143af9eadf9b09fd34a8c391b70"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/dama_doctrine_test_bundle.yaml"
|
||||
]
|
||||
},
|
||||
"doctrine/doctrine-bundle": {
|
||||
"version": "2.13",
|
||||
"recipe": {
|
||||
|
@ -27,6 +39,18 @@
|
|||
"src/Repository/.gitignore"
|
||||
]
|
||||
},
|
||||
"doctrine/doctrine-fixtures-bundle": {
|
||||
"version": "3.7",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "3.0",
|
||||
"ref": "1f5514cfa15b947298df4d771e694e578d4c204d"
|
||||
},
|
||||
"files": [
|
||||
"src/DataFixtures/AppFixtures.php"
|
||||
]
|
||||
},
|
||||
"doctrine/doctrine-migrations-bundle": {
|
||||
"version": "3.3",
|
||||
"recipe": {
|
||||
|
@ -78,6 +102,20 @@
|
|||
"config/packages/nelmio_cors.yaml"
|
||||
]
|
||||
},
|
||||
"phpunit/phpunit": {
|
||||
"version": "9.6",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "9.6",
|
||||
"ref": "7364a21d87e658eb363c5020c072ecfdc12e2326"
|
||||
},
|
||||
"files": [
|
||||
".env.test",
|
||||
"phpunit.xml.dist",
|
||||
"tests/bootstrap.php"
|
||||
]
|
||||
},
|
||||
"ramsey/uuid-doctrine": {
|
||||
"version": "2.1",
|
||||
"recipe": {
|
||||
|
@ -143,6 +181,27 @@
|
|||
"src/Kernel.php"
|
||||
]
|
||||
},
|
||||
"symfony/maker-bundle": {
|
||||
"version": "1.61",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||
}
|
||||
},
|
||||
"symfony/mercure-bundle": {
|
||||
"version": "0.3",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "0.3",
|
||||
"ref": "528285147494380298f8f991ee8c47abebaf79db"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/mercure.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/monolog-bundle": {
|
||||
"version": "3.10",
|
||||
"recipe": {
|
||||
|
@ -155,6 +214,21 @@
|
|||
"config/packages/monolog.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/phpunit-bridge": {
|
||||
"version": "7.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.3",
|
||||
"ref": "a411a0480041243d97382cac7984f7dce7813c08"
|
||||
},
|
||||
"files": [
|
||||
".env.test",
|
||||
"bin/phpunit",
|
||||
"phpunit.xml.dist",
|
||||
"tests/bootstrap.php"
|
||||
]
|
||||
},
|
||||
"symfony/routing": {
|
||||
"version": "6.4",
|
||||
"recipe": {
|
||||
|
@ -218,5 +292,30 @@
|
|||
"files": [
|
||||
"config/packages/validator.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/web-profiler-bundle": {
|
||||
"version": "6.4",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.1",
|
||||
"ref": "e42b3f0177df239add25373083a564e5ead4e13a"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/web_profiler.yaml",
|
||||
"config/routes/web_profiler.yaml"
|
||||
]
|
||||
},
|
||||
"zenstruck/foundry": {
|
||||
"version": "1.38",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.10",
|
||||
"ref": "37c2f894cc098ab4c08874b80cccc8e2f8de7976"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/zenstruck_foundry.yaml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue