From 9576806765c65da198dda980d61b6668ef35508a Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 5 Dec 2020 07:01:26 +0100 Subject: [PATCH] Message sending is now a job --- .../Webhook/StandardMessageGenerator.php | 1 - .../Events/StoredGroupEventHandler.php | 4 + .../Events/UpdatedGroupEventHandler.php | 5 +- app/Handlers/Events/WebhookEventHandler.php | 17 ++-- app/Jobs/SendWebhookMessage.php | 44 +++++++++++ .../Webhook/StandardWebhookSender.php | 77 +++++++------------ .../Webhook/WebhookSenderInterface.php | 5 +- config/queue.php | 50 ++++-------- 8 files changed, 105 insertions(+), 98 deletions(-) create mode 100644 app/Jobs/SendWebhookMessage.php diff --git a/app/Generator/Webhook/StandardMessageGenerator.php b/app/Generator/Webhook/StandardMessageGenerator.php index 51d8abe8be..d71248b13f 100644 --- a/app/Generator/Webhook/StandardMessageGenerator.php +++ b/app/Generator/Webhook/StandardMessageGenerator.php @@ -104,7 +104,6 @@ class StandardMessageGenerator implements MessageGeneratorInterface foreach ($this->webhooks as $webhook) { $this->runWebhook($webhook); } - //event(new RequestedSendWebhookMessages); } /** diff --git a/app/Handlers/Events/StoredGroupEventHandler.php b/app/Handlers/Events/StoredGroupEventHandler.php index 68a9a05e98..f09de7b8a1 100644 --- a/app/Handlers/Events/StoredGroupEventHandler.php +++ b/app/Handlers/Events/StoredGroupEventHandler.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Events; +use FireflyIII\Events\RequestedSendWebhookMessages; use FireflyIII\Events\StoredTransactionGroup; use FireflyIII\Generator\Webhook\MessageGeneratorInterface; use FireflyIII\Models\TransactionJournal; @@ -92,6 +93,9 @@ class StoredGroupEventHandler $engine->setObjects(new Collection([$group])); // tell the generator to generate the messages $engine->generateMessages(); + + // trigger event to send them: + event(new RequestedSendWebhookMessages); } } diff --git a/app/Handlers/Events/UpdatedGroupEventHandler.php b/app/Handlers/Events/UpdatedGroupEventHandler.php index bf98d72774..f5b027c2e5 100644 --- a/app/Handlers/Events/UpdatedGroupEventHandler.php +++ b/app/Handlers/Events/UpdatedGroupEventHandler.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Events; +use FireflyIII\Events\RequestedSendWebhookMessages; use FireflyIII\Events\UpdatedTransactionGroup; use FireflyIII\Generator\Webhook\MessageGeneratorInterface; use FireflyIII\Models\Account; @@ -125,8 +126,10 @@ class UpdatedGroupEventHandler /** @var MessageGeneratorInterface $engine */ $engine = app(MessageGeneratorInterface::class); $engine->setUser($user); - $engine->setTransactionGroups(new Collection([$group])); + $engine->setObjects(new Collection([$group])); $engine->setTrigger(Webhook::TRIGGER_UPDATE_TRANSACTION); $engine->generateMessages(); + + event(new RequestedSendWebhookMessages); } } diff --git a/app/Handlers/Events/WebhookEventHandler.php b/app/Handlers/Events/WebhookEventHandler.php index f4f8e4517c..a7aad48222 100644 --- a/app/Handlers/Events/WebhookEventHandler.php +++ b/app/Handlers/Events/WebhookEventHandler.php @@ -22,14 +22,8 @@ namespace FireflyIII\Handlers\Events; -use Exception; -use FireflyIII\Helpers\Webhook\SignatureGeneratorInterface; -use FireflyIII\Models\WebhookAttempt; +use FireflyIII\Jobs\SendWebhookMessage; use FireflyIII\Models\WebhookMessage; -use FireflyIII\Services\Webhook\WebhookSenderInterface; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\ClientException; -use JsonException; use Log; /** @@ -42,6 +36,7 @@ class WebhookEventHandler */ public function sendWebhookMessages(): void { + // kick offf the job! $messages = WebhookMessage ::where('webhook_messages.sent', 0) ->where('webhook_messages.errored', 0) @@ -52,10 +47,8 @@ class WebhookEventHandler } )->splice(0, 3); Log::debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count())); - - $sender =app(WebhookSenderInterface::class); - $sender->setMessages($messages); - $sender->send(); - + foreach ($messages as $message) { + SendWebhookMessage::dispatch($message)->afterResponse(); + } } } \ No newline at end of file diff --git a/app/Jobs/SendWebhookMessage.php b/app/Jobs/SendWebhookMessage.php new file mode 100644 index 0000000000..c302eda016 --- /dev/null +++ b/app/Jobs/SendWebhookMessage.php @@ -0,0 +1,44 @@ +message = $message; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle(): void + { + // send job! + $sender = app(WebhookSenderInterface::class); + $sender->setMessage($this->message); + $sender->send(); + } +} diff --git a/app/Services/Webhook/StandardWebhookSender.php b/app/Services/Webhook/StandardWebhookSender.php index 95c224d8b3..69d4b7d7fb 100644 --- a/app/Services/Webhook/StandardWebhookSender.php +++ b/app/Services/Webhook/StandardWebhookSender.php @@ -21,22 +21,20 @@ namespace FireflyIII\Services\Webhook; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Webhook\SignatureGeneratorInterface; -use FireflyIII\Models\WebhookAttempt; use FireflyIII\Models\WebhookMessage; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; -use Illuminate\Support\Collection; -use Log; use JsonException; +use Log; + /** * Class StandardWebhookSender */ class StandardWebhookSender implements WebhookSenderInterface { - private Collection $messages; - private int $version = 1; + private WebhookMessage $message; + private int $version = 1; /** * @inheritDoc @@ -49,49 +47,32 @@ class StandardWebhookSender implements WebhookSenderInterface /** * @inheritDoc */ - public function setMessages(Collection $messages): void + public function setMessage(WebhookMessage $message): void { - $this->messages = $messages; + $this->message = $message; } /** * @inheritDoc */ public function send(): void - { - /** @var WebhookMessage $message */ - foreach ($this->messages as $message) { - try { - $this->sendMessage($message); - } catch (FireflyException $e) { - // TODO log attempt and make WebhookAttempt - } - } - } - - /** - * @param WebhookMessage $message - * - * @throws \GuzzleHttp\Exception\GuzzleException - */ - private function sendMessage(WebhookMessage $message): void { // have the signature generator generate a signature. If it fails, the error thrown will // end up in send() to be caught. $signatureGenerator = app(SignatureGeneratorInterface::class); - $signature = $signatureGenerator->generate($message); + $signature = $signatureGenerator->generate($this->message); - Log::debug(sprintf('Trying to send webhook message #%d', $message->id)); + Log::debug(sprintf('Trying to send webhook message #%d', $this->message->id)); try { - $json = json_encode($message->message, JSON_THROW_ON_ERROR); + $json = json_encode($this->message->message, JSON_THROW_ON_ERROR); } catch (JsonException $e) { // TODO throw Firefly Exception -// $attempt = new WebhookAttempt; -// $attempt->webhookMessage()->associate($message); -// $attempt->status_code = 0; -// $attempt->logs = sprintf('Json error: %s', $e->getMessage()); -// $attempt->save(); + // $attempt = new WebhookAttempt; + // $attempt->webhookMessage()->associate($this->message); + // $attempt->status_code = 0; + // $attempt->logs = sprintf('Json error: %s', $e->getMessage()); + // $attempt->save(); return; } @@ -107,32 +88,32 @@ class StandardWebhookSender implements WebhookSenderInterface ], ]; $client = new Client; - //$logs = $message->logs ?? []; + //$logs = $this->message->logs ?? []; try { - $res = $client->request('POST', $message->webhook->url, $options); - $message->sent = true; - } catch (ClientException|Exception $e) { + $res = $client->request('POST', $this->message->webhook->url, $options); + $this->message->sent = true; + } catch (ClientException | Exception $e) { Log::error($e->getMessage()); Log::error($e->getTraceAsString()); //$logs[] = sprintf('%s: %s', date('Y-m-d H:i:s'), $e->getMessage()); - $message->errored = true; - $message->sent = false; + $this->message->errored = true; + $this->message->sent = false; } - $message->save(); + $this->message->save(); -// $attempt = new WebhookAttempt; -// $attempt->webhookMessage()->associate($message); -// $attempt->status_code = $res->getStatusCode(); -// $attempt->logs = ''; -// $attempt->response = (string)$res->getBody(); -// $attempt->save(); + // $attempt = new WebhookAttempt; + // $attempt->webhookMessage()->associate($this->message); + // $attempt->status_code = $res->getStatusCode(); + // $attempt->logs = ''; + // $attempt->response = (string)$res->getBody(); + // $attempt->save(); - Log::debug(sprintf('Webhook message #%d was sent. Status code %d', $message->id, $res->getStatusCode())); + Log::debug(sprintf('Webhook message #%d was sent. Status code %d', $this->message->id, $res->getStatusCode())); Log::debug(sprintf('Webhook request body size: %d bytes', strlen($json))); Log::debug(sprintf('Response body: %s', $res->getBody())); //$sender - //$this->sendMessageV0($message); + //$this->sendMessageV0($this->message); } } \ No newline at end of file diff --git a/app/Services/Webhook/WebhookSenderInterface.php b/app/Services/Webhook/WebhookSenderInterface.php index 3994fcbecc..10f52eaec1 100644 --- a/app/Services/Webhook/WebhookSenderInterface.php +++ b/app/Services/Webhook/WebhookSenderInterface.php @@ -22,7 +22,6 @@ namespace FireflyIII\Services\Webhook; use FireflyIII\Models\WebhookMessage; -use Illuminate\Support\Collection; /** * Interface WebhookSenderInterface @@ -35,9 +34,9 @@ interface WebhookSenderInterface public function getVersion(): int; /** - * @param Collection $messages + * @param WebhookMessage $message */ - public function setMessages(Collection $messages): void; + public function setMessage(WebhookMessage $message): void; /** * diff --git a/config/queue.php b/config/queue.php index d0b341a312..a8bf551583 100644 --- a/config/queue.php +++ b/config/queue.php @@ -1,41 +1,19 @@ . - */ - -declare(strict_types=1); return [ + /* |-------------------------------------------------------------------------- - | Default Queue Driver + | Default Queue Connection Name |-------------------------------------------------------------------------- | | Laravel's queue API supports an assortment of back-ends via a single | API, giving you convenient access to each back-end using the same - | syntax for each one. Here you may set the default queue driver. - | - | Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | syntax for every one. Here you may define a default connection. | */ - 'default' => envNonEmpty('QUEUE_DRIVER', 'sync'), + 'default' => env('QUEUE_CONNECTION', 'sync'), /* |-------------------------------------------------------------------------- @@ -46,6 +24,8 @@ return [ | is used by your application. A default configuration has been added | for each back-end shipped with Laravel. You are free to add more. | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | */ 'connections' => [ @@ -66,22 +46,25 @@ return [ 'host' => 'localhost', 'queue' => 'default', 'retry_after' => 90, + 'block_for' => 0, ], 'sqs' => [ 'driver' => 'sqs', - 'key' => 'your-public-key', - 'secret' => 'your-secret-key', - 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', - 'queue' => 'your-queue-name', - 'region' => 'us-east-1', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'your-queue-name'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', - 'queue' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, + 'block_for' => null, ], ], @@ -98,7 +81,8 @@ return [ */ 'failed' => [ - 'database' => envNonEmpty('DB_CONNECTION', 'pgsql'), + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'mysql'), 'table' => 'failed_jobs', ],