accounts/common/tasks/DeliveryWebHook.php
ErickSkrauch c0aa78d156 Implemented WebHooks delivery queue.
Completely removed usage of the RabbitMQ. Queue now based on Redis channels.
Worker process now extracted as separate docker container.
Base image upgraded to the 1.8.0 version (PHP 7.2.7 and pcntl extension).
2018-07-08 18:20:19 +03:00

111 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace common\tasks;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Yii;
use yii\queue\RetryableJobInterface;
class DeliveryWebHook implements RetryableJobInterface {
/**
* @var string
*/
public $type;
/**
* @var string
*/
public $url;
/**
* @var string|null
*/
public $secret;
/**
* @var array
*/
public $payloads;
/**
* @return int time to reserve in seconds
*/
public function getTtr(): int {
return 65;
}
/**
* @param int $attempt number
* @param \Exception|\Throwable $error from last execute of the job
*
* @return bool
*/
public function canRetry($attempt, $error): bool {
if ($attempt >= 5) {
return false;
}
if ($error instanceof ServerException || $error instanceof ConnectException) {
return true;
}
return false;
}
/**
* @param \yii\queue\Queue $queue which pushed and is handling the job
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function execute($queue): void {
$client = $this->createClient();
try {
$client->request('POST', $this->url, [
'headers' => [
'User-Agent' => 'Account-Ely-Hookshot/' . Yii::$app->version,
'X-Ely-Accounts-Event' => $this->type,
],
'form_params' => $this->payloads,
]);
} catch (ClientException $e) {
Yii::info("Delivery for {$this->url} has failed with {$e->getResponse()->getStatusCode()} status.");
return;
}
}
protected function createClient(): ClientInterface {
return new GuzzleClient([
'handler' => $this->createStack(),
'timeout' => 60,
'connect_timeout' => 10,
]);
}
protected function createStack(): HandlerStack {
$stack = HandlerStack::create();
$stack->push(Middleware::mapRequest(function(RequestInterface $request): RequestInterface {
if (empty($this->secret)) {
return $request;
}
$payload = (string)$request->getBody();
$signature = hash_hmac('sha1', $payload, $this->secret);
/** @noinspection ExceptionsAnnotatingAndHandlingInspection */
return $request->withHeader('X-Hub-Signature', 'sha1=' . $signature);
}));
return $stack;
}
}