Skip to content

Commit bfb5963

Browse files
committed
feature symfony#49815 [HttpClient][Messenger] add PingWebhookMessage and PingWebhookMessageHandler (kbond)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [HttpClient][Messenger] add `PingWebhookMessage` and `PingWebhookMessageHandler` | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | n/a | License | MIT | Doc PR | todo With symfony/scheduler, it could be useful to ping some kind of uptime monitoring service like [ohdearapp](https://ohdear.app/). ## Usage ```php use Symfony\Component\HttpClient\Messenger\PingWebhookMessage; $bus->dispatch(new PingWebhookMessage('GET', 'https://example.com')); // simple ping, throws HttpExceptionInterface on 3xx/4xx/5xx $bus->dispatch(new PingWebhookMessage('GET', 'https://example.com', throw: false)); // ping, but does not throw HttpExceptionInterface on 3xx/4xx/5xx $bus->dispatch(new PingWebhookMessage('GET', 'https://example.com', [ 'headers' => ['X-FOO => 'bar'], // any HttpClientInterface options ])); ``` TODO: - [x] wire up - [x] tests Commits ------- f0644d9 [HttpClient][Messenger] add `PingWebhookMessage` and `PingWebhookMessageHandler`
2 parents 6c817f2 + f0644d9 commit bfb5963

File tree

7 files changed

+159
-0
lines changed

7 files changed

+159
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
use Symfony\Component\HtmlSanitizer\HtmlSanitizer;
8484
use Symfony\Component\HtmlSanitizer\HtmlSanitizerConfig;
8585
use Symfony\Component\HtmlSanitizer\HtmlSanitizerInterface;
86+
use Symfony\Component\HttpClient\Messenger\PingWebhookMessageHandler;
8687
use Symfony\Component\HttpClient\MockHttpClient;
8788
use Symfony\Component\HttpClient\Retry\GenericRetryStrategy;
8889
use Symfony\Component\HttpClient\RetryableHttpClient;
@@ -2462,6 +2463,10 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder
24622463
unset($options['vars']);
24632464
$container->getDefinition('http_client.transport')->setArguments([$options, $config['max_host_connections'] ?? 6]);
24642465

2466+
if (!class_exists(PingWebhookMessageHandler::class)) {
2467+
$container->removeDefinition('http_client.messenger.ping_webhook_handler');
2468+
}
2469+
24652470
if (!$hasPsr18 = ContainerBuilder::willBeAvailable('psr/http-client', ClientInterface::class, ['symfony/framework-bundle', 'symfony/http-client'])) {
24662471
$container->removeDefinition('psr18.http_client');
24672472
$container->removeAlias(ClientInterface::class);

src/Symfony/Bundle/FrameworkBundle/Resources/config/http_client.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Psr\Http\Message\StreamFactoryInterface;
1818
use Symfony\Component\HttpClient\HttpClient;
1919
use Symfony\Component\HttpClient\HttplugClient;
20+
use Symfony\Component\HttpClient\Messenger\PingWebhookMessageHandler;
2021
use Symfony\Component\HttpClient\Psr18Client;
2122
use Symfony\Component\HttpClient\Retry\GenericRetryStrategy;
2223
use Symfony\Component\HttpClient\UriTemplateHttpClient;
@@ -90,5 +91,11 @@
9091
->args([
9192
[inline_service(\Rize\UriTemplate::class), 'expand'],
9293
])
94+
95+
->set('http_client.messenger.ping_webhook_handler', PingWebhookMessageHandler::class)
96+
->args([
97+
service('http_client'),
98+
])
99+
->tag('messenger.message_handler')
93100
;
94101
};

src/Symfony/Component/HttpClient/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add `HarFileResponseFactory` testing utility, allow to replay responses from `.har` files
88
* Add `max_retries` option to `RetryableHttpClient` to adjust the retry logic on a per request level
9+
* Add `PingWehookMessage` and `PingWebhookMessageHandler`
910

1011
6.3
1112
---
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpClient\Messenger;
13+
14+
/**
15+
* @author Kevin Bond <[email protected]>
16+
*/
17+
final class PingWebhookMessage implements \Stringable
18+
{
19+
public function __construct(
20+
public readonly string $method,
21+
public readonly string $url,
22+
public readonly array $options = [],
23+
public readonly bool $throw = true,
24+
) {
25+
}
26+
27+
public function __toString(): string
28+
{
29+
return "[{$this->method}] {$this->url}";
30+
}
31+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpClient\Messenger;
13+
14+
use Symfony\Contracts\HttpClient\HttpClientInterface;
15+
use Symfony\Contracts\HttpClient\ResponseInterface;
16+
17+
/**
18+
* @author Kevin Bond <[email protected]>
19+
*/
20+
class PingWebhookMessageHandler
21+
{
22+
public function __construct(
23+
private readonly HttpClientInterface $httpClient,
24+
) {
25+
}
26+
27+
public function __invoke(PingWebhookMessage $message): ResponseInterface
28+
{
29+
$response = $this->httpClient->request($message->method, $message->url, $message->options);
30+
$response->getHeaders($message->throw);
31+
32+
return $response;
33+
}
34+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpClient\Tests\Messenger;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpClient\Exception\ClientException;
16+
use Symfony\Component\HttpClient\Messenger\PingWebhookMessage;
17+
use Symfony\Component\HttpClient\Messenger\PingWebhookMessageHandler;
18+
use Symfony\Component\HttpClient\MockHttpClient;
19+
use Symfony\Component\HttpClient\Response\MockResponse;
20+
21+
/**
22+
* @author Kevin Bond <[email protected]>
23+
*/
24+
final class PingWebhookMessageHandlerTest extends TestCase
25+
{
26+
public function testSuccessfulPing()
27+
{
28+
$client = new MockHttpClient([
29+
function ($method, $url) {
30+
$this->assertSame('POST', $method);
31+
$this->assertSame('https://endpoint.com/key', $url);
32+
33+
return new MockResponse('a response');
34+
},
35+
]);
36+
$handler = new PingWebhookMessageHandler($client);
37+
$response = $handler(new PingWebhookMessage('POST', 'https://endpoint.com/key'));
38+
39+
$this->assertSame(200, $response->getStatusCode());
40+
$this->assertSame('a response', $response->getContent());
41+
$this->assertSame('https://endpoint.com/key', $response->getInfo('url'));
42+
}
43+
44+
public function testPingErrorThrowsException()
45+
{
46+
$client = new MockHttpClient([
47+
function ($method, $url) {
48+
$this->assertSame('POST', $method);
49+
$this->assertSame('https://endpoint.com/key', $url);
50+
51+
return new MockResponse('a response', ['http_code' => 404]);
52+
},
53+
]);
54+
55+
$handler = new PingWebhookMessageHandler($client);
56+
57+
$this->expectException(ClientException::class);
58+
59+
$handler(new PingWebhookMessage('POST', 'https://endpoint.com/key'));
60+
}
61+
62+
public function testPingErrorDoesNotThrowException()
63+
{
64+
$client = new MockHttpClient([
65+
function ($method, $url) {
66+
$this->assertSame('POST', $method);
67+
$this->assertSame('https://endpoint.com/key', $url);
68+
69+
return new MockResponse('a response', ['http_code' => 404]);
70+
},
71+
]);
72+
73+
$handler = new PingWebhookMessageHandler($client);
74+
$response = $handler(new PingWebhookMessage('POST', 'https://endpoint.com/key', throw: false));
75+
76+
$this->assertSame(404, $response->getStatusCode());
77+
$this->assertSame('a response', $response->getContent(false));
78+
$this->assertSame('https://endpoint.com/key', $response->getInfo('url'));
79+
}
80+
}

src/Symfony/Component/HttpClient/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"psr/http-client": "^1.0",
4040
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
4141
"symfony/http-kernel": "^5.4|^6.0|^7.0",
42+
"symfony/messenger": "^5.4|^6.0|^7.0",
4243
"symfony/process": "^5.4|^6.0|^7.0",
4344
"symfony/stopwatch": "^5.4|^6.0|^7.0"
4445
},

0 commit comments

Comments
 (0)