Skip to content

Commit

Permalink
Merge branch 'master' into performance-improvement-canonicals
Browse files Browse the repository at this point in the history
  • Loading branch information
grubolsch authored Aug 6, 2024
2 parents a088335 + cc6442c commit 44c7a26
Show file tree
Hide file tree
Showing 24 changed files with 770 additions and 96 deletions.
48 changes: 48 additions & 0 deletions app/Console/Command/BulkRemoveFromProduction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace CultuurNet\UDB3\Console\Command;

use CultuurNet\UDB3\Event\Productions\ProductionId;
use CultuurNet\UDB3\Event\Productions\RemoveEventsFromProduction;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

final class BulkRemoveFromProduction extends AbstractCommand
{
protected function configure(): void
{
$this->setName('event:bulk-remove-from-production')
->setDescription('Bulk removes events from a production')
->addArgument(
'productionId',
InputOption::VALUE_REQUIRED,
'The id of the production contains incorrect events.'
)
->addOption(
'eventId',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'An array of eventIds to remove from the production.'
);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$eventIds = $input->getOption('eventId');
$productionId = $input->getArgument('productionId');

$this->commandBus->dispatch(
new RemoveEventsFromProduction(
$eventIds,
ProductionId::fromNative($productionId)
)
);

$output->writeln(count($eventIds) . ' events were removed from production with id ' . $productionId);

return 0;
}
}
129 changes: 129 additions & 0 deletions app/Console/Command/MoveEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

declare(strict_types=1);

namespace CultuurNet\UDB3\Console\Command;

use Broadway\CommandHandling\CommandBus;
use CultuurNet\UDB3\Event\Commands\UpdateLocation;
use CultuurNet\UDB3\Event\ValueObjects\LocationId;
use CultuurNet\UDB3\Search\ResultsGenerator;
use CultuurNet\UDB3\Search\ResultsGeneratorInterface;
use CultuurNet\UDB3\Search\SearchServiceInterface;
use CultuurNet\UDB3\Search\Sorting;
use Exception;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;

/**
* @url https://jira.publiq.be/browse/III-6228
*/
class MoveEvents extends AbstractCommand
{
private const PLACE_UUID = 'place-uuid';
private const QUERY = 'query';
private const FORCE = 'force';
private const DRY_RUN = 'dry-run';

private ResultsGeneratorInterface $searchResultsGenerator;

public function __construct(
CommandBus $commandBus,
SearchServiceInterface $searchService
) {
parent::__construct($commandBus);
$this->searchResultsGenerator = new ResultsGenerator(
$searchService,
new Sorting('created', 'asc'),
100
);
}

public function configure(): void
{
$this
->setName('event:move')
->setDescription('Update the location of all events from the given SAPI3 query to the given new location')
->addArgument(
self::PLACE_UUID,
null,
'Place uuid to move events to.'
)
->addArgument(
self::QUERY,
null,
'SAPI3 query for which events to move.'
)
->addOption(
self::FORCE,
null,
InputOption::VALUE_NONE,
'Skip confirmation.'
)
->addOption(
self::DRY_RUN,
null,
InputOption::VALUE_NONE,
'Execute the script as a dry run.'
);
}

protected function execute(InputInterface $input, OutputInterface $output): ?int
{
$placeUuid = $input->getArgument(self::PLACE_UUID);
$query = $input->getArgument(self::QUERY);

if ($placeUuid === null || $query === null) {
$output->writeln('<error>Missing argument, the correct syntax is: event:move "place_uuid_to_move_to" "sapi3_query"</error>');
return self::FAILURE;
}

$query = str_replace('q=', '', $query);

$count = $this->searchResultsGenerator->count($query);

if ($count <= 0) {
$output->writeln('<error>No events found</error>');
return self::SUCCESS;
}

if (!$this->askConfirmation($input, $output, $count)) {
return self::SUCCESS;
}

foreach ($this->searchResultsGenerator->search($query) as $event) {
try {
$command = new UpdateLocation($event->getId(), new LocationId($placeUuid));
$output->writeln('Dispatching UpdateLocation for event with id ' . $command->getItemId());

if (!$input->getOption(self::DRY_RUN)) {
$this->commandBus->dispatch($command);
}
} catch (Exception $exception) {
$output->writeln(sprintf('<error>Event with id: %s caused an exception: %s</error>', $event->getId(), $exception->getMessage()));
}
}

return self::SUCCESS;
}

private function askConfirmation(InputInterface $input, OutputInterface $output, int $count): bool
{
if ($input->getOption(self::FORCE)) {
return true;
}

return $this
->getHelper('question')
->ask(
$input,
$output,
new ConfirmationQuestion(
sprintf('This action will move %d events, continue? [y/N] ', $count),
true
)
);
}
}
17 changes: 14 additions & 3 deletions app/Console/Command/ProcessDuplicatePlaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use CultuurNet\UDB3\Place\Canonical\Exception\MuseumPassNotUniqueInCluster;
use CultuurNet\UDB3\ReadModel\DocumentEventFactory;
use Doctrine\DBAL\Connection;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -38,21 +39,25 @@ final class ProcessDuplicatePlaces extends AbstractCommand

private Connection $connection;

private LoggerInterface $logger;

public function __construct(
CommandBus $commandBus,
DuplicatePlaceRepository $duplicatePlaceRepository,
CanonicalService $canonicalService,
EventBus $eventBus,
DocumentEventFactory $placeEventFactory,
EventRelationsRepository $eventRelationsRepository,
Connection $connection
Connection $connection,
LoggerInterface $logger
) {
$this->duplicatePlaceRepository = $duplicatePlaceRepository;
$this->canonicalService = $canonicalService;
$this->eventBus = $eventBus;
$this->placeEventFactory = $placeEventFactory;
$this->eventRelationsRepository = $eventRelationsRepository;
$this->connection = $connection;
$this->logger = $logger;

parent::__construct($commandBus);
}
Expand Down Expand Up @@ -95,7 +100,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
$onlyRunClusterId = $input->getOption(self::ONLY_RUN_CLUSTER_ID);

if ($onlyRunClusterId) {
$clusterIds = [(int)$onlyRunClusterId];
$clusterIds = [$onlyRunClusterId];
} else {
$clusterIds = $this->duplicatePlaceRepository->getClusterIds();
}
Expand Down Expand Up @@ -152,7 +157,12 @@ public function execute(InputInterface $input, OutputInterface $output): int
foreach ($commands as $command) {
$output->writeln('Dispatching UpdateLocation for event with id ' . $command->getItemId());
if (!$dryRun) {
$this->commandBus->dispatch($command);
try {
$this->commandBus->dispatch($command);
} catch (\Exception $e) {
$output->writeln('<error>' . $e->getMessage() . '</error>');
$this->logger->error($e->getMessage());
}
}
}
}
Expand Down Expand Up @@ -203,6 +213,7 @@ private function reindexPlaces(array $placesToReIndex, OutputInterface $output,
$this->eventBus->publish(
new DomainEventStream([(new DomainMessageBuilder())->create($placeProjected)])
);
$this->duplicatePlaceRepository->markAsProcessed($placeToReIndex);
}
}
}
Expand Down
23 changes: 22 additions & 1 deletion app/Console/ConsoleServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Broadway\EventHandling\EventBus;
use Broadway\UuidGenerator\Rfc4122\Version4Generator;
use CultuurNet\UDB3\Console\Command\BulkRemoveFromProduction;
use CultuurNet\UDB3\Console\Command\ChangeOfferOwner;
use CultuurNet\UDB3\Console\Command\ChangeOfferOwnerInBulk;
use CultuurNet\UDB3\Console\Command\ChangeOrganizerOwner;
Expand All @@ -28,6 +29,7 @@
use CultuurNet\UDB3\Console\Command\ImportOfferAutoClassificationLabels;
use CultuurNet\UDB3\Console\Command\IncludeLabel;
use CultuurNet\UDB3\Console\Command\KeycloakCommand;
use CultuurNet\UDB3\Console\Command\MoveEvents;
use CultuurNet\UDB3\Console\Command\ProcessDuplicatePlaces;
use CultuurNet\UDB3\Console\Command\PurgeModelCommand;
use CultuurNet\UDB3\Console\Command\ReindexEventsWithRecommendations;
Expand Down Expand Up @@ -76,10 +78,12 @@ final class ConsoleServiceProvider extends AbstractServiceProvider
'console.place:geocode',
'console.place:delete',
'console.event:geocode',
'console.event:move',
'console.organizer:geocode',
'console.fire-projected-to-jsonld-for-relations',
'console.fire-projected-to-jsonld',
'console.place:process-duplicates',
'console.event:bulk-remove-from-production',
'console.event:reindex-offers-with-popularity',
'console.place:reindex-offers-with-popularity',
'console.event:reindex-events-with-recommendations',
Expand Down Expand Up @@ -214,6 +218,14 @@ function () use ($container) {
)
);

$container->addShared(
'console.event:move',
fn () => new MoveEvents(
$container->get('event_command_bus'),
$container->get(EventsSapi3SearchService::class),
)
);

$container->addShared(
'console.fire-projected-to-jsonld-for-relations',
fn () => new FireProjectedToJSONLDForRelationsCommand(
Expand Down Expand Up @@ -242,10 +254,19 @@ function () use ($container) {
$container->get(EventBus::class),
$container->get('place_jsonld_projected_event_factory'),
$container->get(EventRelationsRepository::class),
$container->get('dbal_connection')
$container->get('dbal_connection'),
LoggerFactory::create(
$container,
LoggerName::forService('duplicate-place', 'duplicate.places')
)
)
);

$container->addShared(
'console.event:bulk-remove-from-production',
fn () => new BulkRemoveFromProduction($container->get('event_command_bus'))
);

$container->addShared(
'console.event:reindex-offers-with-popularity',
fn () => new ReindexOffersWithPopularityScore(
Expand Down
3 changes: 2 additions & 1 deletion app/Event/EventCommandHandlerProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ function () use ($container): UpdateUiTPASPricesHandler {
function () use ($container): CopyEventHandler {
return new CopyEventHandler(
$container->get('event_repository'),
$container->get(ProductionRepository::class)
$container->get(ProductionRepository::class),
$container->get('config')['add_copied_event_to_parent_production'] ?? true
);
}
);
Expand Down
51 changes: 51 additions & 0 deletions app/Migrations/Version20240718143512.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace CultuurNet\UDB3\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration;

final class Version20240718143512 extends AbstractMigration
{
public function up(Schema $schema): void
{
$table = $schema->getTable('duplicate_places');

$table->changeColumn(
'cluster_id',
[
'type' => Type::getType(Types::STRING),
'length' => 40, //SHA1 length
]
);

$table->addColumn('created_date', Types::DATETIME_IMMUTABLE);

$table->addColumn(
'processed',
Types::BOOLEAN,
['default' => false]
)
->setNotnull(true);
}

public function down(Schema $schema): void
{
$table = $schema->getTable('duplicate_places');

$table->dropColumn('created_date');
$table->dropColumn('processed');

$table->changeColumn(
'cluster_id',
[
'type' => Type::getType(Types::BIGINT),
'length' => 40, //SHA1 length
]
);
}
}
Loading

0 comments on commit 44c7a26

Please sign in to comment.