From 0db726db8af0c0c1c47368d961f5d9f1aab7b5da Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 12:13:56 +0100 Subject: [PATCH 1/8] PS-722 fix workflow update event trigger --- lib/php/workflow/src/Executor/JobExecutor.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/php/workflow/src/Executor/JobExecutor.php b/lib/php/workflow/src/Executor/JobExecutor.php index 40337f492..a2366f4e4 100644 --- a/lib/php/workflow/src/Executor/JobExecutor.php +++ b/lib/php/workflow/src/Executor/JobExecutor.php @@ -177,11 +177,11 @@ private function dispatchEvent(JobUpdateEvent $event): void } } - private function persistJobState(JobState $jobState): void + private function persistJobState(JobState $jobState, bool $releaseLock = true): void { $this->stateRepository->persistJobState($jobState); - if ($this->stateRepository instanceof LockAwareStateRepositoryInterface) { + if ($releaseLock && $this->stateRepository instanceof LockAwareStateRepositoryInterface) { $this->stateRepository->releaseJobLock($jobState->getWorkflowId(), $jobState->getId()); } @@ -241,7 +241,7 @@ private function runJob(JobExecutionContext $context, Job $job): void if ($runContext->isRetainJob()) { $this->extractOutputs($job, $context); - $this->stateRepository->persistJobState($jobState); + $this->persistJobState($jobState, releaseLock: false); return; } @@ -252,7 +252,7 @@ private function runJob(JobExecutionContext $context, Job $job): void $jobState->setEndedAt(new MicroDateTime()); $jobState->setStatus($endStatus); - $this->stateRepository->persistJobState($jobState); + $this->persistJobState($jobState, releaseLock: false); } private function getJobCallable(Step $step, JobExecutionContext $context, RunContext $runContext): callable From 678cbfda07bc21c031042383917b33c7859451eb Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 16:19:37 +0100 Subject: [PATCH 2/8] add easyadmin filters --- .../Admin/AssetRenditionCrudController.php | 15 ++++++++- .../Admin/AttributeCrudController.php | 12 ++++++- .../Filter/ChildPropertyEntityFilter.php | 33 ++++++++++++++++--- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/databox/api/src/Controller/Admin/AssetRenditionCrudController.php b/databox/api/src/Controller/Admin/AssetRenditionCrudController.php index cc5bd9881..a5b8685ac 100644 --- a/databox/api/src/Controller/Admin/AssetRenditionCrudController.php +++ b/databox/api/src/Controller/Admin/AssetRenditionCrudController.php @@ -6,8 +6,10 @@ use Alchemy\AdminBundle\Field\CodeField; use Alchemy\AdminBundle\Field\IdField; use Alchemy\AdminBundle\Field\JsonField; +use Alchemy\AdminBundle\Filter\AssociationIdentifierFilter; use Alchemy\AdminBundle\Filter\ChildPropertyEntityFilter; use App\Entity\Core\AssetRendition; +use App\Entity\Core\Workspace; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -15,7 +17,9 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; +use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter; use EasyCorp\Bundle\EasyAdminBundle\Filter\DateTimeFilter; +use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter; use EasyCorp\Bundle\EasyAdminBundle\Filter\NullFilter; class AssetRenditionCrudController extends AbstractAdminCrudController @@ -45,9 +49,18 @@ public function configureCrud(Crud $crud): Crud public function configureFilters(Filters $filters): Filters { return $filters - ->add(ChildPropertyEntityFilter::new('definition', 'workspace', 'Workspace')) + ->add(ChildPropertyEntityFilter::new( + 'definition', + 'workspace', + Workspace::class, + 'Workspace' + )) + ->add(EntityFilter::new('definition')) + ->add(AssociationIdentifierFilter::new('asset')) ->add(NullFilter::new('file', 'Is Ready')->setChoiceLabels('Not ready', 'Ready')) ->add(DateTimeFilter::new('createdAt')) + ->add(BooleanFilter::new('locked')) + ->add(BooleanFilter::new('substituted')) ; } diff --git a/databox/api/src/Controller/Admin/AttributeCrudController.php b/databox/api/src/Controller/Admin/AttributeCrudController.php index 614e8cbd3..964ff00cf 100644 --- a/databox/api/src/Controller/Admin/AttributeCrudController.php +++ b/databox/api/src/Controller/Admin/AttributeCrudController.php @@ -5,8 +5,10 @@ use Alchemy\AdminBundle\Controller\AbstractAdminCrudController; use Alchemy\AdminBundle\Field\IdField; use Alchemy\AdminBundle\Field\JsonField; +use Alchemy\AdminBundle\Filter\AssociationIdentifierFilter; use Alchemy\AdminBundle\Filter\ChildPropertyEntityFilter; use App\Entity\Core\Attribute; +use App\Entity\Core\Workspace; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -19,6 +21,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Filter\BooleanFilter; +use EasyCorp\Bundle\EasyAdminBundle\Filter\EntityFilter; use EasyCorp\Bundle\EasyAdminBundle\Filter\TextFilter; class AttributeCrudController extends AbstractAdminCrudController @@ -38,7 +41,14 @@ public function configureActions(Actions $actions): Actions public function configureFilters(Filters $filters): Filters { return $filters - ->add(ChildPropertyEntityFilter::new('definition', 'workspace', 'Workspace')) + ->add(ChildPropertyEntityFilter::new( + 'definition', + 'workspace', + Workspace::class, + 'Workspace' + )) + ->add(EntityFilter::new('definition')) + ->add(AssociationIdentifierFilter::new('asset')) ->add(TextFilter::new('value')) ->add(TextFilter::new('locale')) ->add(BooleanFilter::new('locked')) diff --git a/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php b/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php index dff8b7963..4fb056feb 100644 --- a/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php +++ b/lib/php/admin-bundle/Filter/ChildPropertyEntityFilter.php @@ -14,6 +14,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDataDto; +use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDto; use EasyCorp\Bundle\EasyAdminBundle\Filter\FilterTrait; use EasyCorp\Bundle\EasyAdminBundle\Form\Filter\Type\EntityFilterType; use EasyCorp\Bundle\EasyAdminBundle\Form\Type\ComparisonType; @@ -24,17 +25,25 @@ final class ChildPropertyEntityFilter implements FilterInterface { use FilterTrait; - public static function new(string $propertyName, string $childPropertyName, $label = null): self + private string $realPropertyName; + private string $subPropertyName; + + + public static function new(string $propertyName, string $childPropertyName, string $entityClass, $label = null): self { $label = null == $label ? $childPropertyName : $label; return (new self()) ->setFilterFqcn(__CLASS__) - ->setProperty($propertyName) + ->setRealPropertyName($propertyName) + ->setSubPropertyName($childPropertyName) + ->setProperty(sprintf('%s__%s', $propertyName, $childPropertyName)) ->setLabel($label) ->setFormType(EntityFilterType::class) ->setFormTypeOption('translation_domain', 'EasyAdminBundle') - ->setFormTypeOption('value_type_options.attr.data-child-property', $childPropertyName); + ->setFormTypeOption('value_type_options.attr.data-child-property', $childPropertyName) + ->setFormTypeOption('value_type_options.class', $entityClass) + ; } /** @@ -48,13 +57,13 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, $assocAlias = 'ea_'.$filterDataDto->getParameterName(); $childAssocAlias = 'ea_'.$filterDataDto->getParameter2Name(); - $property = $filterDataDto->getProperty(); + $property = $this->realPropertyName; $comparison = $filterDataDto->getComparison(); $parameterName = $filterDataDto->getParameterName(); $value = $filterDataDto->getValue(); $isMultiple = $filterDataDto->getFormTypeOption('value_type_options.multiple'); - $childPropertyName = $filterDataDto->getFormTypeOption('value_type_options.attr.data-child-property'); + $childPropertyName = $this->subPropertyName; $doctrineMetadata = $entityDto->getPropertyMetadata($property); $entityManager = $queryBuilder->getEntityManager(); $propertyEntityFqcn = $doctrineMetadata->get('targetEntity'); @@ -155,4 +164,18 @@ private function processSingleParameterValue(QueryBuilder $queryBuilder, mixed $ return $parameterValue; } + + public function setRealPropertyName(string $realPropertyName): self + { + $this->realPropertyName = $realPropertyName; + + return $this; + } + + public function setSubPropertyName(string $subPropertyName): self + { + $this->subPropertyName = $subPropertyName; + + return $this; + } } From c371d56951788050cacd28aadc003514d88e5a60 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 16:45:03 +0100 Subject: [PATCH 3/8] PS-723 cascade delete AssetDataTemplate --- .../src/Doctrine/Delete/CollectionDelete.php | 36 ++++++++++++++----- .../src/Doctrine/Delete/WorkspaceDelete.php | 12 +++++-- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/databox/api/src/Doctrine/Delete/CollectionDelete.php b/databox/api/src/Doctrine/Delete/CollectionDelete.php index 703a1933b..d5c1863d6 100644 --- a/databox/api/src/Doctrine/Delete/CollectionDelete.php +++ b/databox/api/src/Doctrine/Delete/CollectionDelete.php @@ -10,12 +10,16 @@ use App\Entity\Core\Asset; use App\Entity\Core\Collection; use App\Entity\Core\CollectionAsset; +use App\Entity\Template\AssetDataTemplate; use Doctrine\ORM\EntityManagerInterface; final readonly class CollectionDelete { - public function __construct(private EntityManagerInterface $em, private IndexCleaner $indexCleaner, private SoftDeleteToggler $softDeleteToggler) - { + public function __construct( + private EntityManagerInterface $em, + private IndexCleaner $indexCleaner, + private SoftDeleteToggler $softDeleteToggler, + ) { } public function deleteCollection(string $collectionId, bool $isChildProcess = false): void @@ -79,13 +83,6 @@ private function doDelete(string $collectionId): void ->getQuery() ->toIterable(); - foreach ($assets as $a) { - $asset = $this->em->find(Asset::class, $a['id']); - $this->em->remove($asset); - $this->em->flush(); - $this->em->clear(); - } - $this->em->getRepository(CollectionAsset::class) ->createQueryBuilder('t') ->delete() @@ -94,10 +91,31 @@ private function doDelete(string $collectionId): void ->getQuery() ->execute(); + foreach ($assets as $a) { + $asset = $this->em->find(Asset::class, $a['id']); + $this->em->remove($asset); + $this->em->flush(); + $this->em->clear(); + } + + $this->deleteDependencies(AssetDataTemplate::class, $collectionId); + $collection = $this->em->find(Collection::class, $collectionId); if ($collection instanceof Collection) { $this->em->remove($collection); $this->em->flush(); } } + + private function deleteDependencies(string $entityClass, string $collectionId): void + { + $items = $this->em->getRepository($entityClass)->findBy([ + 'collection' => $collectionId, + ]); + foreach ($items as $item) { + $this->em->remove($item); + } + $this->em->flush(); + $this->em->clear(); + } } diff --git a/databox/api/src/Doctrine/Delete/WorkspaceDelete.php b/databox/api/src/Doctrine/Delete/WorkspaceDelete.php index b640c2522..8611ab0c9 100644 --- a/databox/api/src/Doctrine/Delete/WorkspaceDelete.php +++ b/databox/api/src/Doctrine/Delete/WorkspaceDelete.php @@ -15,12 +15,17 @@ use App\Entity\Core\RenditionDefinition; use App\Entity\Core\Tag; use App\Entity\Core\Workspace; +use App\Entity\Template\AssetDataTemplate; use Doctrine\ORM\EntityManagerInterface; -class WorkspaceDelete +final readonly class WorkspaceDelete { - public function __construct(private readonly EntityManagerInterface $em, private readonly CollectionDelete $collectionDelete, private readonly IndexCleaner $indexCleaner, private readonly SoftDeleteToggler $softDeleteToggler) - { + public function __construct( + private EntityManagerInterface $em, + private CollectionDelete $collectionDelete, + private IndexCleaner $indexCleaner, + private SoftDeleteToggler $softDeleteToggler, + ) { } public function deleteWorkspace(string $workspaceId): void @@ -62,6 +67,7 @@ public function deleteWorkspace(string $workspaceId): void $this->deleteDependencies(RenditionClass::class, $workspaceId); $this->deleteDependencies(AttributeDefinition::class, $workspaceId); $this->deleteDependencies(AttributeClass::class, $workspaceId); + $this->deleteDependencies(AssetDataTemplate::class, $workspaceId); $files = $this->em->getRepository(File::class) ->createQueryBuilder('t') From 4546f5fd67609c9805c732b9e333a8b5eafa6eb8 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 16:51:41 +0100 Subject: [PATCH 4/8] fix API-PHP-K6 --- databox/api/src/Controller/Admin/AttributeCrudController.php | 2 +- .../Controller/MessengerMessageCrudController.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/databox/api/src/Controller/Admin/AttributeCrudController.php b/databox/api/src/Controller/Admin/AttributeCrudController.php index 964ff00cf..130ae71c5 100644 --- a/databox/api/src/Controller/Admin/AttributeCrudController.php +++ b/databox/api/src/Controller/Admin/AttributeCrudController.php @@ -60,7 +60,7 @@ public function configureCrud(Crud $crud): Crud return parent::configureCrud($crud) ->setEntityLabelInSingular('Attribute') ->setEntityLabelInPlural('Attribute') - ->setSearchFields(['id', 'locale', 'position', 'translationId', 'translationOriginHash', 'value', 'origin', 'originVendor', 'originUserId', 'originVendorContext', 'coordinates', 'status', 'confidence']) + ->setSearchFields(['id', 'locale', 'position', 'translationOriginHash', 'value', 'origin', 'originVendor', 'originUserId', 'originVendorContext', 'coordinates', 'status', 'confidence']) ->setPaginatorPageSize(20); } diff --git a/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php b/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php index e10b796eb..57806e712 100644 --- a/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php +++ b/lib/php/messenger-bundle/Controller/MessengerMessageCrudController.php @@ -16,6 +16,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; +use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\Messenger\MessageBusInterface; @@ -70,7 +71,8 @@ public function retry(AdminContext $context): RedirectResponse $this->em->persist($message); $this->em->flush(); - return new RedirectResponse($context->getReferrer()); + return $this->redirect($context->getReferrer() + ?? $this->container->get(AdminUrlGenerator::class)->setAction(Action::INDEX)->generateUrl()); } public function configureCrud(Crud $crud): Crud From ee106dd8a14f5ad14f7eb16ed85bff1fe119b2d1 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 17:12:34 +0100 Subject: [PATCH 5/8] fix API-PHP-K2 --- .../messenger-bundle/Listener/SentryMessengerListener.php | 8 ++++---- lib/php/rendition-factory/src/Command/CreateCommand.php | 2 +- .../src/Context/TransformationContext.php | 7 ++++++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/php/messenger-bundle/Listener/SentryMessengerListener.php b/lib/php/messenger-bundle/Listener/SentryMessengerListener.php index 991eacd73..e37cb6747 100644 --- a/lib/php/messenger-bundle/Listener/SentryMessengerListener.php +++ b/lib/php/messenger-bundle/Listener/SentryMessengerListener.php @@ -50,12 +50,12 @@ public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): $scope->setTag('messenger.message_bus', $messageBusStamp->getBusName()); } - $scope->setExtras([ - 'Messenger Message' => get_debug_type($envelope->getMessage()), - 'Messenger Payload' => $this->serializer->serialize( + $scope->setContext('messenger', [ + 'Message' => get_debug_type($envelope->getMessage()), + 'Payload' => $this->serializer->serialize( $envelope->getMessage(), JsonEncoder::FORMAT, [ - JsonEncode::OPTIONS => JSON_PRETTY_PRINT + JsonEncode::OPTIONS => JSON_PRETTY_PRINT, ] ), ]); diff --git a/lib/php/rendition-factory/src/Command/CreateCommand.php b/lib/php/rendition-factory/src/Command/CreateCommand.php index 6dd533b96..3fc870e70 100644 --- a/lib/php/rendition-factory/src/Command/CreateCommand.php +++ b/lib/php/rendition-factory/src/Command/CreateCommand.php @@ -56,7 +56,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (null === $mimeType) { $mimeType = $this->mimeTypeGuesser->guessMimeTypeFromPath($src); - $output->writeln(sprintf('MIME type guessed: %s', $mimeType)); + $output->writeln(sprintf('MIME type guessed: %s', $mimeType ?? 'unknown')); } $buildConfig = $this->yamlLoader->load($input->getArgument('build-config')); diff --git a/lib/php/rendition-factory/src/Context/TransformationContext.php b/lib/php/rendition-factory/src/Context/TransformationContext.php index c56039842..6f2447329 100644 --- a/lib/php/rendition-factory/src/Context/TransformationContext.php +++ b/lib/php/rendition-factory/src/Context/TransformationContext.php @@ -48,7 +48,12 @@ public function getCacheDir(string $folder): string public function guessMimeTypeFromPath(string $path): string { - return $this->mimeTypeGuesser->guessMimeTypeFromPath($path); + $mimeType = $this->mimeTypeGuesser->guessMimeTypeFromPath($path); + if (empty($mimeType)) { + throw new \RuntimeException(sprintf('Could not guess mime type for file "%s"', $path)); + } + + return $mimeType; } public function getExtension(string $mimeType): ?string From 1861a0aa3e3a10ad8d8b4897615112b166df4296 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 17:51:42 +0100 Subject: [PATCH 6/8] improve sentry --- databox/api/config/bundles.php | 2 +- databox/api/config/packages/messenger.yaml | 1 + expose/api/config/bundles.php | 2 +- expose/api/config/packages/messenger.yaml | 3 +++ .../Controller/SentryTestController.php | 20 +++++++++++++++++ .../AlchemyCoreExtension.php | 2 ++ .../core-bundle/Message/Debug/SentryDebug.php | 22 +++++++++++++++++++ .../Message/Debug/SentryDebugHandler.php | 14 ++++++++++++ .../core-bundle/Resources/config/sentry.yaml | 1 + .../Listener/SentryMessengerListener.php | 4 +--- notify/api/config/bundles.php | 2 +- notify/api/config/packages/messenger.yaml | 3 +++ uploader/api/config/bundles.php | 2 +- uploader/api/config/packages/messenger.yaml | 3 +++ 14 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 lib/php/core-bundle/Message/Debug/SentryDebug.php create mode 100644 lib/php/core-bundle/Message/Debug/SentryDebugHandler.php diff --git a/databox/api/config/bundles.php b/databox/api/config/bundles.php index 50835713d..fe0b86f76 100644 --- a/databox/api/config/bundles.php +++ b/databox/api/config/bundles.php @@ -30,7 +30,7 @@ Alchemy\WorkflowBundle\AlchemyWorkflowBundle::class => ['all' => true], Alchemy\ESBundle\AlchemyESBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Arthem\ObjectReferenceBundle\ArthemObjectReferenceBundle::class => ['all' => true], Alchemy\RenditionFactoryBundle\AlchemyRenditionFactoryBundle::class => ['all' => true], ]; diff --git a/databox/api/config/packages/messenger.yaml b/databox/api/config/packages/messenger.yaml index 16672517f..10d6e30b2 100644 --- a/databox/api/config/packages/messenger.yaml +++ b/databox/api/config/packages/messenger.yaml @@ -14,6 +14,7 @@ framework: Alchemy\Workflow\Message\JobConsumer: p1 Alchemy\WebhookBundle\Consumer\WebhookTriggerMessage: p2 Alchemy\WebhookBundle\Consumer\WebhookEvent: p2 + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 when@dev: framework: diff --git a/expose/api/config/bundles.php b/expose/api/config/bundles.php index 6882f3890..aaa4655d0 100644 --- a/expose/api/config/bundles.php +++ b/expose/api/config/bundles.php @@ -24,6 +24,6 @@ Exercise\HTMLPurifierBundle\ExerciseHTMLPurifierBundle::class => ['all' => true], Alchemy\NotifyBundle\AlchemyNotifyBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], ]; diff --git a/expose/api/config/packages/messenger.yaml b/expose/api/config/packages/messenger.yaml index cc60768e3..228be678a 100644 --- a/expose/api/config/packages/messenger.yaml +++ b/expose/api/config/packages/messenger.yaml @@ -5,6 +5,9 @@ framework: dsn: '%alchemy_messenger.amqp_transport_dsn%/p1' options: '%alchemy_messenger.amqp_transport_options%' + routing: + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 + when@dev: framework: messenger: diff --git a/lib/php/core-bundle/Controller/SentryTestController.php b/lib/php/core-bundle/Controller/SentryTestController.php index 6ed5fbb39..00d078cc3 100644 --- a/lib/php/core-bundle/Controller/SentryTestController.php +++ b/lib/php/core-bundle/Controller/SentryTestController.php @@ -4,10 +4,12 @@ namespace Alchemy\CoreBundle\Controller; +use Alchemy\CoreBundle\Message\Debug\SentryDebug; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; +use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Annotation\Route; #[Route(path: '/_health/sentry-test')] @@ -40,4 +42,22 @@ public function testBoth(): never throw new \RuntimeException('[BOTH] Exception'); } + + #[Route(path: '/log-stack')] + public function logStack(): never + { + $this->logger->debug('This is a DEBUG log'); + $this->logger->info('This is a INFO log'); + $this->logger->error('This is a ERROR log'); + + throw new \RuntimeException('Stack'); + } + + #[Route(path: '/messenger')] + public function messenger(MessageBusInterface $bus): Response + { + $bus->dispatch(new SentryDebug(date(\DateTimeInterface::ATOM), ['extra' => 'data'])); + + return new Response(''); + } } diff --git a/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php b/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php index d947697d6..f9c3c22fc 100644 --- a/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php +++ b/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php @@ -150,8 +150,10 @@ public function prepend(ContainerBuilder $container): void ], ]); } + if (isset($bundles['SentryBundle'])) { $container->prependExtensionConfig('sentry', [ + 'dsn' => $env === 'prod' ? '%env(SENTRY_DSN)%' : null, 'tracing' => [ 'dbal' => [ 'enabled' => false, diff --git a/lib/php/core-bundle/Message/Debug/SentryDebug.php b/lib/php/core-bundle/Message/Debug/SentryDebug.php new file mode 100644 index 000000000..41f926b02 --- /dev/null +++ b/lib/php/core-bundle/Message/Debug/SentryDebug.php @@ -0,0 +1,22 @@ +id; + } + + public function getExtra(): array + { + return $this->extra; + } +} diff --git a/lib/php/core-bundle/Message/Debug/SentryDebugHandler.php b/lib/php/core-bundle/Message/Debug/SentryDebugHandler.php new file mode 100644 index 000000000..745993ff1 --- /dev/null +++ b/lib/php/core-bundle/Message/Debug/SentryDebugHandler.php @@ -0,0 +1,14 @@ +getId())); + } +} diff --git a/lib/php/core-bundle/Resources/config/sentry.yaml b/lib/php/core-bundle/Resources/config/sentry.yaml index 758b9c41f..063de3ca7 100644 --- a/lib/php/core-bundle/Resources/config/sentry.yaml +++ b/lib/php/core-bundle/Resources/config/sentry.yaml @@ -9,6 +9,7 @@ services: autoconfigure: true Alchemy\CoreBundle\Controller\SentryTestController: ~ + Alchemy\CoreBundle\Message\Debug\SentryDebugHandler: ~ Sentry\Monolog\Handler: arguments: diff --git a/lib/php/messenger-bundle/Listener/SentryMessengerListener.php b/lib/php/messenger-bundle/Listener/SentryMessengerListener.php index e37cb6747..9d24bac73 100644 --- a/lib/php/messenger-bundle/Listener/SentryMessengerListener.php +++ b/lib/php/messenger-bundle/Listener/SentryMessengerListener.php @@ -40,9 +40,6 @@ public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): $envelope = $event->getEnvelope(); $exception = $event->getThrowable(); - $scope->setTag('messenger.receiver_name', $event->getReceiverName()); - $scope->setTag('messenger.message_class', \get_class($envelope->getMessage())); - /** @var BusNameStamp|null $messageBusStamp */ $messageBusStamp = $envelope->last(BusNameStamp::class); @@ -58,6 +55,7 @@ public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): JsonEncode::OPTIONS => JSON_PRETTY_PRINT, ] ), + 'ReceiverName' => $event->getReceiverName(), ]); $this->captureException($exception, $event->willRetry()); diff --git a/notify/api/config/bundles.php b/notify/api/config/bundles.php index a62c2bdb9..390f616e7 100644 --- a/notify/api/config/bundles.php +++ b/notify/api/config/bundles.php @@ -12,6 +12,6 @@ Alchemy\AdminBundle\AlchemyAdminBundle::class => ['all' => true], EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], ]; diff --git a/notify/api/config/packages/messenger.yaml b/notify/api/config/packages/messenger.yaml index cc60768e3..228be678a 100644 --- a/notify/api/config/packages/messenger.yaml +++ b/notify/api/config/packages/messenger.yaml @@ -5,6 +5,9 @@ framework: dsn: '%alchemy_messenger.amqp_transport_dsn%/p1' options: '%alchemy_messenger.amqp_transport_options%' + routing: + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 + when@dev: framework: messenger: diff --git a/uploader/api/config/bundles.php b/uploader/api/config/bundles.php index e332b2900..33480728a 100644 --- a/uploader/api/config/bundles.php +++ b/uploader/api/config/bundles.php @@ -27,6 +27,6 @@ Alchemy\StorageBundle\AlchemyStorageBundle::class => ['all' => true], Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], Oneup\FlysystemBundle\OneupFlysystemBundle::class => ['all' => true], - Sentry\SentryBundle\SentryBundle::class => ['prod' => true], + Sentry\SentryBundle\SentryBundle::class => ['all' => true], Alchemy\MessengerBundle\AlchemyMessengerBundle::class => ['all' => true], ]; diff --git a/uploader/api/config/packages/messenger.yaml b/uploader/api/config/packages/messenger.yaml index 76191dc2d..ef018a2b1 100644 --- a/uploader/api/config/packages/messenger.yaml +++ b/uploader/api/config/packages/messenger.yaml @@ -11,6 +11,9 @@ framework: dsn: '%alchemy_messenger.amqp_transport_dsn%/p3' options: '%alchemy_messenger.amqp_transport_options%' + routing: + Alchemy\CoreBundle\Message\Debug\SentryDebug: p1 + when@dev: framework: messenger: From 1752cd08114a15af03df649f89f2712db0bbe8fb Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 18:05:39 +0100 Subject: [PATCH 7/8] fix mime type from watermark --- lib/php/core-bundle/Util/UrlUtil.php | 5 ++++ .../Context/ReadOnlyTransformationContext.php | 2 +- .../src/Context/TransformationContext.php | 30 ++++++++++++------- .../TransformationContextInterface.php | 2 +- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/php/core-bundle/Util/UrlUtil.php b/lib/php/core-bundle/Util/UrlUtil.php index 194bf5c85..18f92e5d3 100644 --- a/lib/php/core-bundle/Util/UrlUtil.php +++ b/lib/php/core-bundle/Util/UrlUtil.php @@ -24,6 +24,11 @@ public static function removeQueryParamFromUrl(string $url, string $key): string return $baseUrl.'?'.$query; } + public static function getUriWithoutQuery(string $url): string + { + return strtok($url, '?'); + } + public static function extractUrlParameters(string $url): ?array { $parts = parse_url($url); diff --git a/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php b/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php index f2efc96bc..73cb6bf74 100644 --- a/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php +++ b/lib/php/rendition-factory/src/Context/ReadOnlyTransformationContext.php @@ -25,7 +25,7 @@ public function getCacheDir(string $folder): string throw new \InvalidArgumentException('Cannot get cache directory in read-only context'); } - public function guessMimeTypeFromPath(string $path): string + public function guessMimeTypeFromPath(string $path): ?string { return $this->mimeTypeGuesser->guessMimeTypeFromPath($path); } diff --git a/lib/php/rendition-factory/src/Context/TransformationContext.php b/lib/php/rendition-factory/src/Context/TransformationContext.php index 6f2447329..97af1eb42 100644 --- a/lib/php/rendition-factory/src/Context/TransformationContext.php +++ b/lib/php/rendition-factory/src/Context/TransformationContext.php @@ -2,6 +2,7 @@ namespace Alchemy\RenditionFactory\Context; +use Alchemy\CoreBundle\Util\UrlUtil; use Alchemy\RenditionFactory\DTO\Metadata\MetadataContainerInterface; use Alchemy\RenditionFactory\MimeType\MimeTypeGuesser; use Psr\Log\LoggerInterface; @@ -46,14 +47,9 @@ public function getCacheDir(string $folder): string return $cacheDir; } - public function guessMimeTypeFromPath(string $path): string + public function guessMimeTypeFromPath(string $path): ?string { - $mimeType = $this->mimeTypeGuesser->guessMimeTypeFromPath($path); - if (empty($mimeType)) { - throw new \RuntimeException(sprintf('Could not guess mime type for file "%s"', $path)); - } - - return $mimeType; + return $this->mimeTypeGuesser->guessMimeTypeFromPath($path); } public function getExtension(string $mimeType): ?string @@ -64,18 +60,23 @@ public function getExtension(string $mimeType): ?string public function getRemoteFile(string $uri): string { $cacheDir = $this->getCacheDir('remote'); - $mimeType = $this->guessMimeTypeFromPath($uri); - $extension = $this->getExtension($mimeType); + $mimeType = $this->guessMimeTypeFromPath(UrlUtil::getUriWithoutQuery($uri)); + $extension = null !== $mimeType ? $this->getExtension($mimeType) : null; $path = $cacheDir.'/'.md5($uri).($extension ? '.'.$extension : ''); if (!file_exists($path)) { - $this->download($uri, $path); + $contentType = $this->download($uri, $path); + if (null === $mimeType && null !== $contentType) { + $newPath = $path.'.'.$this->getExtension($contentType); + rename($path, $newPath); + $path = $newPath; + } } return $path; } - private function download(string $uri, string $dest): void + private function download(string $uri, string $dest): ?string { $response = $this->client->request('GET', $uri); @@ -84,6 +85,13 @@ private function download(string $uri, string $dest): void fwrite($fileHandler, $chunk->getContent()); } fclose($fileHandler); + + $contentType = $response->getHeaders()['content-type'] ?? null; + if (empty($contentType)) { + return null; + } + + return is_array($contentType) ? $contentType[0] : $contentType; } public function getMetadata(string $name): ?string diff --git a/lib/php/rendition-factory/src/Context/TransformationContextInterface.php b/lib/php/rendition-factory/src/Context/TransformationContextInterface.php index e568b00e1..88278d409 100644 --- a/lib/php/rendition-factory/src/Context/TransformationContextInterface.php +++ b/lib/php/rendition-factory/src/Context/TransformationContextInterface.php @@ -8,7 +8,7 @@ public function createTmpFilePath(?string $extension): string; public function getCacheDir(string $folder): string; - public function guessMimeTypeFromPath(string $path): string; + public function guessMimeTypeFromPath(string $path): ?string; public function getExtension(string $mimeType): ?string; From 3e024dd301ba3cfdb6c81dfa4ddda337171f3193 Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Thu, 14 Nov 2024 18:18:07 +0100 Subject: [PATCH 8/8] fix sentry config for prod --- .../DependencyInjection/AlchemyCoreExtension.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php b/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php index f9c3c22fc..df5d22ba9 100644 --- a/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php +++ b/lib/php/core-bundle/DependencyInjection/AlchemyCoreExtension.php @@ -152,8 +152,7 @@ public function prepend(ContainerBuilder $container): void } if (isset($bundles['SentryBundle'])) { - $container->prependExtensionConfig('sentry', [ - 'dsn' => $env === 'prod' ? '%env(SENTRY_DSN)%' : null, + $sentryConfig = [ 'tracing' => [ 'dbal' => [ 'enabled' => false, @@ -183,7 +182,12 @@ public function prepend(ContainerBuilder $container): void NotAcceptableHttpException::class, ], ], - ]); + ]; + + if ($env !== 'prod') { + $sentryConfig['dsn'] = null; + } + $container->prependExtensionConfig('sentry', $sentryConfig); if (isset($bundles['MonologBundle'])) { $container->prependExtensionConfig('sentry', [