vendor/shopware/core/Framework/Webhook/Subscriber/RetryWebhookMessageFailedSubscriber.php line 48

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Webhook\Subscriber;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  6. use Shopware\Core\Framework\Log\Package;
  7. use Shopware\Core\Framework\Webhook\Event\RetryWebhookMessageFailedEvent;
  8. use Shopware\Core\Framework\Webhook\EventLog\WebhookEventLogDefinition;
  9. use Shopware\Core\Framework\Webhook\Message\WebhookEventMessage;
  10. use Shopware\Core\Framework\Webhook\WebhookEntity;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. /**
  13. * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  14. */
  15. #[Package('core')]
  16. class RetryWebhookMessageFailedSubscriber implements EventSubscriberInterface
  17. {
  18. private const MAX_WEBHOOK_ERROR_COUNT = 10;
  19. private const MAX_DEAD_MESSAGE_ERROR_COUNT = 2;
  20. private EntityRepositoryInterface $deadMessageRepository;
  21. private EntityRepositoryInterface $webhookRepository;
  22. private EntityRepositoryInterface $webhookEventLogRepository;
  23. /**
  24. * @internal
  25. */
  26. public function __construct(
  27. EntityRepositoryInterface $deadMessageRepository,
  28. EntityRepositoryInterface $webhookRepository,
  29. EntityRepositoryInterface $webhookEventLogRepository
  30. ) {
  31. $this->deadMessageRepository = $deadMessageRepository;
  32. $this->webhookRepository = $webhookRepository;
  33. $this->webhookEventLogRepository = $webhookEventLogRepository;
  34. }
  35. public static function getSubscribedEvents(): array
  36. {
  37. return [RetryWebhookMessageFailedEvent::class => ['handleWebhookMessageFail']];
  38. }
  39. public function handleWebhookMessageFail(RetryWebhookMessageFailedEvent $event): void
  40. {
  41. $deadMessage = $event->getDeadMessage();
  42. $context = $event->getContext();
  43. if ($deadMessage->getErrorCount() < self::MAX_DEAD_MESSAGE_ERROR_COUNT) {
  44. return;
  45. }
  46. /** @var WebhookEventMessage $webhookEventMessage */
  47. $webhookEventMessage = $deadMessage->getOriginalMessage();
  48. $webhookId = $webhookEventMessage->getWebhookId();
  49. $webhookEventLogId = $webhookEventMessage->getWebhookEventId();
  50. $this->deleteDeadMessage($deadMessage->getId(), $context);
  51. $this->markWebhookEventFailed($webhookEventLogId, $context);
  52. /** @var WebhookEntity|null $webhook */
  53. $webhook = $this->webhookRepository
  54. ->search(new Criteria([$webhookId]), $context)
  55. ->get($webhookId);
  56. if ($webhook === null || !$webhook->isActive()) {
  57. return;
  58. }
  59. $webhookErrorCount = $webhook->getErrorCount() + 1;
  60. $params = [
  61. 'id' => $webhook->getId(),
  62. 'errorCount' => $webhookErrorCount,
  63. ];
  64. if ($webhookErrorCount >= self::MAX_WEBHOOK_ERROR_COUNT) {
  65. $params = array_merge($params, [
  66. 'errorCount' => 0,
  67. 'active' => false,
  68. ]);
  69. }
  70. $this->webhookRepository->update([$params], $context);
  71. }
  72. private function deleteDeadMessage(string $deadMessageId, Context $context): void
  73. {
  74. $this->deadMessageRepository->delete([
  75. [
  76. 'id' => $deadMessageId,
  77. ],
  78. ], $context);
  79. }
  80. private function markWebhookEventFailed(string $webhookEventLogId, Context $context): void
  81. {
  82. $this->webhookEventLogRepository->update([
  83. [
  84. 'id' => $webhookEventLogId,
  85. 'deliveryStatus' => WebhookEventLogDefinition::STATUS_FAILED,
  86. ],
  87. ], $context);
  88. }
  89. }