Skip to content

Commit 4dbb634

Browse files
authored
Merge pull request #64 from MacPaw/develop
New Release
2 parents c2f17c1 + 55cebe8 commit 4dbb634

16 files changed

+254
-62
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77

88
jobs:
99
run:
10-
runs-on: ubuntu-18.04
10+
runs-on: ubuntu-latest
1111
strategy:
1212
fail-fast: false
1313
matrix:

README.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ symfony_health_check:
7171
ping_checks:
7272
- id: symfony_health_check.status_up_check
7373
```
74+
Change response code:
75+
- default response code is 200.
76+
- determine your custom response code in case of some check fails (Response code must be a valid HTTP status code)
77+
```yaml
78+
symfony_health_check:
79+
health_checks:
80+
- id: symfony_health_check.doctrine_check
81+
ping_checks:
82+
- id: symfony_health_check.status_up_check
83+
ping_error_response_code: 500
84+
health_error_response_code: 404
85+
```
7486
7587
Create Symfony Health Check Bundle Routing Config:
7688
----------------------------------
@@ -141,12 +153,12 @@ You can change the default behavior with a light configuration, remember to retu
141153
health:
142154
path: /your/custom/url
143155
methods: GET
144-
controller: SymfonyHealthCheckBundle\Controller\HealthController::healthCheckAction
156+
controller: SymfonyHealthCheckBundle\Controller\HealthController::check
145157
146158
ping:
147159
path: /your/custom/url
148160
methods: GET
149-
controller: SymfonyHealthCheckBundle\Controller\PingController::pingAction
161+
controller: SymfonyHealthCheckBundle\Controller\PingController::check
150162
151163
```
152164

SECURITY.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
| Version | Supported |
66
| ------- | ------------------ |
77
| 0.x.x | :white_check_mark: |
8+
| 1.x.x | :white_check_mark: |
89

910
## Reporting a Bug
1011

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"require-dev": {
3636
"ext-json": "*",
3737
"phpstan/phpstan": "1.9.*",
38-
"squizlabs/php_codesniffer": "3.5.*",
38+
"squizlabs/php_codesniffer": "3.7.*",
3939
"symfony/phpunit-bridge": "^3.4 || ^4.1.12 || ^5.0 || ^6.0",
4040
"phpunit/phpunit": "^8.5 || ^9.0",
4141
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",

phpstan-baseline.neon

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
parameters:
22
ignoreErrors:
33
-
4-
message: '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children\(\).#'
4+
message: '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface::variableNode\(\).#'
55
count: 1
66
path: ./src/DependencyInjection
77
-

src/Check/DoctrineCheck.php

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public function check(): Response
2525
return new Response(self::CHECK_RESULT_NAME, false, 'Entity Manager Not Found.');
2626
}
2727

28+
/**
29+
* @var object|null $entityManager
30+
*/
2831
$entityManager = $this->container->get('doctrine.orm.entity_manager');
2932

3033
if ($entityManager === null) {

src/Controller/BaseController.php

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SymfonyHealthCheckBundle\Controller;
6+
7+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
8+
use Symfony\Component\HttpFoundation\JsonResponse;
9+
use Symfony\Component\HttpFoundation\Response;
10+
use SymfonyHealthCheckBundle\Check\CheckInterface;
11+
12+
abstract class BaseController extends AbstractController
13+
{
14+
/**
15+
* @var array<CheckInterface>
16+
*/
17+
private array $checks = [];
18+
private ?int $customResponseCode = null;
19+
20+
abstract public function check(): JsonResponse;
21+
22+
public function addHealthCheck(CheckInterface $check): void
23+
{
24+
$this->checks[] = $check;
25+
}
26+
27+
public function setCustomResponseCode(?int $code): void
28+
{
29+
$this->customResponseCode = $code;
30+
}
31+
32+
protected function checkAction(): JsonResponse
33+
{
34+
$checkResult = $this->performCheck();
35+
$responseCode = $this->determineResponseCode($checkResult);
36+
37+
return new JsonResponse($checkResult, $responseCode);
38+
}
39+
40+
protected function performCheck(): array
41+
{
42+
return array_map(
43+
fn($healthCheck) => $healthCheck->check()->toArray(),
44+
$this->checks
45+
);
46+
}
47+
48+
protected function determineResponseCode(array $results): int
49+
{
50+
$code = $this->customResponseCode;
51+
$responseCode = Response::HTTP_OK;
52+
53+
if (null !== $code) {
54+
foreach ($results as $result) {
55+
if (!$result['result']) {
56+
$responseCode = $code;
57+
break;
58+
}
59+
}
60+
}
61+
62+
return $responseCode;
63+
}
64+
}

src/Controller/HealthController.php

+3-21
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,20 @@
44

55
namespace SymfonyHealthCheckBundle\Controller;
66

7-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
87
use Symfony\Component\HttpFoundation\JsonResponse;
9-
use Symfony\Component\HttpFoundation\Response;
108
use Symfony\Component\Routing\Annotation\Route;
11-
use SymfonyHealthCheckBundle\Check\CheckInterface;
129

13-
final class HealthController extends AbstractController
10+
final class HealthController extends BaseController
1411
{
15-
/**
16-
* @var array<CheckInterface>
17-
*/
18-
private array $healthChecks = [];
19-
20-
public function addHealthCheck(CheckInterface $healthCheck): void
21-
{
22-
$this->healthChecks[] = $healthCheck;
23-
}
24-
2512
/**
2613
* @Route(
2714
* path="/health",
2815
* name="health",
2916
* methods={"GET"}
3017
* )
3118
*/
32-
public function healthCheckAction(): JsonResponse
19+
public function check(): JsonResponse
3320
{
34-
$resultHealthCheck = [];
35-
foreach ($this->healthChecks as $healthCheck) {
36-
$resultHealthCheck[] = $healthCheck->check()->toArray();
37-
}
38-
39-
return new JsonResponse($resultHealthCheck, Response::HTTP_OK);
21+
return $this->checkAction();
4022
}
4123
}

src/Controller/PingController.php

+3-21
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,20 @@
44

55
namespace SymfonyHealthCheckBundle\Controller;
66

7-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
87
use Symfony\Component\HttpFoundation\JsonResponse;
9-
use Symfony\Component\HttpFoundation\Response;
108
use Symfony\Component\Routing\Annotation\Route;
11-
use SymfonyHealthCheckBundle\Check\CheckInterface;
129

13-
final class PingController extends AbstractController
10+
final class PingController extends BaseController
1411
{
15-
/**
16-
* @var array<CheckInterface>
17-
*/
18-
private array $checks = [];
19-
20-
public function addHealthCheck(CheckInterface $check): void
21-
{
22-
$this->checks[] = $check;
23-
}
24-
2512
/**
2613
* @Route(
2714
* path="/ping",
2815
* name="ping",
2916
* methods={"GET"}
3017
* )
3118
*/
32-
public function pingAction(): JsonResponse
19+
public function check(): JsonResponse
3320
{
34-
$pingCheck = [];
35-
foreach ($this->checks as $healthCheck) {
36-
$pingCheck[] = $healthCheck->check()->toArray();
37-
}
38-
39-
return new JsonResponse($pingCheck, Response::HTTP_OK);
21+
return $this->checkAction();
4022
}
4123
}

src/DependencyInjection/Configuration.php

+19
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
88
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
99
use Symfony\Component\Config\Definition\ConfigurationInterface;
10+
use Symfony\Component\HttpFoundation\Response;
1011

1112
class Configuration implements ConfigurationInterface
1213
{
@@ -21,6 +22,24 @@ public function getConfigTreeBuilder(): TreeBuilder
2122

2223
$root
2324
->children()
25+
->variableNode('ping_error_response_code')
26+
->defaultValue(null)
27+
->validate()
28+
->ifTrue(function ($value) {
29+
return $value !== null && !array_key_exists($value, Response::$statusTexts);
30+
})
31+
->thenInvalid('The ping_error_response_code must be valid HTTP status code or null.')
32+
->end()
33+
->end()
34+
->variableNode('health_error_response_code')
35+
->defaultValue(null)
36+
->validate()
37+
->ifTrue(function ($value) {
38+
return $value !== null && !array_key_exists($value, Response::$statusTexts);
39+
})
40+
->thenInvalid('The health_error_response_code must be valid HTTP status code or null.')
41+
->end()
42+
->end()
2443
->arrayNode('health_checks')
2544
->prototype('array')
2645
->children()

src/DependencyInjection/SymfonyHealthCheckExtension.php

+2
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ private function loadHealthChecks(
3737
foreach ($config['health_checks'] as $healthCheckConfig) {
3838
$healthCheckDefinition = new Reference($healthCheckConfig['id']);
3939
$healthCheckCollection->addMethodCall('addHealthCheck', [$healthCheckDefinition]);
40+
$healthCheckCollection->addMethodCall('setCustomResponseCode', [$config['health_error_response_code']]);
4041
}
4142

4243
$pingCollection = $container->findDefinition(PingController::class);
4344
foreach ($config['ping_checks'] as $healthCheckConfig) {
4445
$healthCheckDefinition = new Reference($healthCheckConfig['id']);
4546
$pingCollection->addMethodCall('addHealthCheck', [$healthCheckDefinition]);
47+
$pingCollection->addMethodCall('setCustomResponseCode', [$config['ping_error_response_code']]);
4648
}
4749
}
4850
}

src/Resources/config/routes.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
<route
88
id="health"
99
path="/health"
10-
controller="SymfonyHealthCheckBundle\Controller\HealthController::healthCheckAction"
10+
controller="SymfonyHealthCheckBundle\Controller\HealthController::check"
1111
methods="GET"
1212
/>
1313
<route
1414
id="ping"
1515
path="/ping"
16-
controller="SymfonyHealthCheckBundle\Controller\PingController::pingAction"
16+
controller="SymfonyHealthCheckBundle\Controller\PingController::check"
1717
methods="GET"
1818
/>
1919
</routes>

src/SymfonyHealthCheckBundle.php

-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@
88

99
class SymfonyHealthCheckBundle extends Bundle
1010
{
11-
1211
}

tests/Integration/Controller/HealthControllerTest.php

+42-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function testAddCheckStatusUpSuccess(): void
2929
$healthController = new HealthController();
3030
$healthController->addHealthCheck(new StatusUpCheck());
3131

32-
$response = $healthController->healthCheckAction();
32+
$response = $healthController->check();
3333

3434
self::assertSame(200, $response->getStatusCode());
3535
self::assertSame(
@@ -45,7 +45,7 @@ public function testEnvironmentCheckCouldNotDetermine(): void
4545
$healthController = new HealthController();
4646
$healthController->addHealthCheck(new EnvironmentCheck(new ContainerBuilder()));
4747

48-
$response = $healthController->healthCheckAction();
48+
$response = $healthController->check();
4949

5050
self::assertSame(200, $response->getStatusCode());
5151
self::assertSame(
@@ -64,7 +64,7 @@ public function testDoctrineCheckServiceNotFoundException(): void
6464
$healthController = new HealthController();
6565
$healthController->addHealthCheck(new DoctrineCheck(new ContainerBuilder()));
6666

67-
$response = $healthController->healthCheckAction();
67+
$response = $healthController->check();
6868
self::assertSame(200, $response->getStatusCode());
6969
self::assertSame(
7070
json_encode([[
@@ -83,7 +83,7 @@ public function testTwoCheckSuccess(): void
8383
$healthController->addHealthCheck(new StatusUpCheck());
8484
$healthController->addHealthCheck(new EnvironmentCheck(new ContainerBuilder()));
8585

86-
$response = $healthController->healthCheckAction();
86+
$response = $healthController->check();
8787

8888
self::assertSame(200, $response->getStatusCode());
8989
self::assertSame(
@@ -108,7 +108,7 @@ public function testEnvironmentCheckSuccess(): void
108108
{
109109
$healthController = new HealthController();
110110
$healthController->addHealthCheck(new EnvironmentCheck(static::bootKernel()->getContainer()));
111-
$response = $healthController->healthCheckAction();
111+
$response = $healthController->check();
112112

113113
self::assertSame(200, $response->getStatusCode());
114114
self::assertSame(
@@ -131,4 +131,41 @@ public function testAddCheckFailed(): void
131131
$healthController = new HealthController();
132132
$healthController->addHealthCheck(new HealthController());
133133
}
134+
135+
public function testCustomErrorCodeIfOneOfChecksIsFalse(): void
136+
{
137+
$healthController = new HealthController();
138+
$healthController->addHealthCheck(new EnvironmentCheck(new ContainerBuilder()));
139+
$healthController->setCustomResponseCode(500);
140+
141+
$response = $healthController->check();
142+
143+
self::assertSame(500, $response->getStatusCode());
144+
self::assertSame(
145+
json_encode([[
146+
'name' => 'environment',
147+
'result' => false,
148+
'message' => 'Could not determine',
149+
'params' => []
150+
]]),
151+
$response->getContent()
152+
);
153+
}
154+
155+
public function testCustomErrorCodeDoesNotAffectSuccessResponse(): void
156+
{
157+
$healthController = new HealthController();
158+
$healthController->addHealthCheck(new StatusUpCheck());
159+
$healthController->setCustomResponseCode(500);
160+
161+
$response = $healthController->check();
162+
163+
self::assertSame(200, $response->getStatusCode());
164+
self::assertSame(
165+
json_encode([[
166+
'name' => 'status', 'result' => true, 'message' => 'up', 'params' => [],
167+
]]),
168+
$response->getContent()
169+
);
170+
}
134171
}

0 commit comments

Comments
 (0)