Skip to content

Health endpoint #581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Resources/config/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ commongateway_core_metrics:
resource: "@CoreBundle/src/Controller/MetricsController.php"
prefix: /
type: annotation

commongateway_core_health:
resource: "@CoreBundle/src/Controller/HealthController.php"
prefix: /
type: annotation

commongateway_core_fileupload:
resource: "@CoreBundle/src/Controller/FileController.php"
Expand Down
143 changes: 143 additions & 0 deletions src/Controller/HealthController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

// src/Controller/MetricsController.php
namespace CommonGateway\CoreBundle\Controller;

use CommonGateway\CoreBundle\Service\MetricsService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use MongoDB\Client;
use App\Entity\Database;
use MongoDB\Driver\Exception\Exception as MongoDBException;
use Exception;

/**
* The Health controller provides a health check endpoint.
*
* Authors: Conduction <info@conduction.nl> Barry Brands <barry@conduction.nl>
*
* @license EUPL <https://github.com/ConductionNL/contactcatalogus/blob/master/LICENSE.md>
*
* @category Controller
*/
class HealthController extends AbstractController
{

/**
* @var MetricsService The metrics service
*/
private MetricsService $metricsService;

/**
* @var ParameterBagInterface The parameterbaginterface
*/
private ParameterBagInterface $parameterBagInterface;

/**
* @var EntityManagerInterface The entityManagerInterface
*/
private EntityManagerInterface $entityManager;

/**
* The constructor sets al needed variables.
*
* @param MetricsService $metricsService The metrics service
* @param ParameterBagInterface $parameters The Parameter bag
* @param EntityManagerInterface $entityManager The Parameter bag
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docblock description incorrect

*/
public function __construct(MetricsService $metricsService, ParameterBagInterface $parameters, EntityManagerInterface $entityManager)
{
$this->metricsService = $metricsService;
$this->parameters = $parameters;
$this->entityManager = $entityManager;

}//end __construct()

/**
* Provides a health check endpoint.
*
* @return Response
*
* @Route("/health-check", methods={"GET"})
*/
public function healthCheck(Request $request): Response
{
$acceptHeader = ($request->headers->get('Accept') ?? 'application/json');

$status = 'pass';
$outputMessage = null;
$responseStatusCode = 200;
$mongoDBCacheStatus = 'pass';

try {
$client = new Client($this->parameters->get('cache_url'));
$client->listDatabases();
} catch (Exception | MongoDBException $e) {
$mongoDBCacheStatus = 'fail';
$status = 'fail';
$outputMessage = 'The cache MongoDB connection failed: '.$e->getMessage();
$responseStatusCode = 400;
}

$objectDatabases = $this->entityManager->getRepository(Database::class)->findAll();
$mongoDBCount = count($objectDatabases);
$mongoDBPassCount = 0;
$mongoDBFailCount = 0;

foreach ($objectDatabases as $database) {
try {
$client = new Client($database->getUri());
$client->listDatabases();
$mongoDBPassCount++;
} catch (Exception | MongoDBException $e) {
$mongoDBFailCount++;
}
}

if ($mongoDBFailCount > 0) {
if ($status !== 'fail') {
$status = 'warn';
}

$responseStatusCode = 400;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would throw a 500-range here

$message = 'ome database connections failed: '.(string) $mongoDBFailCount.' out of '.(string) $mongoDBCount.' connections';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ome?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case he combines 2 messages he uses lower s and if this is the start of the message he uses capital S

$outputMessage = $outputMessage ? $outputMessage .= ' and s'.$message : $outputMessage = 'S'.$message;
}

try {
$errors = $this->metricsService->getErrors();
} catch (Exception $e) {
$status = 'fail';
$errors = null;
$outputMessage = $outputMessage ? $outputMessage .= ' and could not fetch error logs: '.$e->getMessage() : $outputMessage = 'Could not fetch error logs: '.$e->getMessage();
$responseStatusCode = 400;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, 400 range sounds like the test does something wrong, instead of that there's an error on the server

}

$responseArray = [
'status' => $status,
'version' => '0.1.0',
'description' => 'This is an instance of the CommonGateway',
'notes' => [],
'output' => $outputMessage,
'checks' => [
'errors' => $errors,
'mongodb' => [
'cache' => $mongoDBCacheStatus,
'otherConnections' => [
'total' => $mongoDBCount,
'pass' => $mongoDBPassCount,
'fail' => $mongoDBFailCount,
],
],

],
];

return new Response(json_encode($responseArray), $responseStatusCode, ['Content-Type' => $acceptHeader]);

}//end healthCheck()
}//end class
Loading