From b6a5e8519a9f5f9931276c5f520e1c579fe5c896 Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Thu, 23 May 2024 01:34:52 +0200 Subject: [PATCH 1/4] Added health controller --- src/Controller/HealthController.php | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/Controller/HealthController.php diff --git a/src/Controller/HealthController.php b/src/Controller/HealthController.php new file mode 100644 index 00000000..0e75a893 --- /dev/null +++ b/src/Controller/HealthController.php @@ -0,0 +1,56 @@ + Barry Brands + * + * @license EUPL + * + * @category Controller + */ +class HealthController extends AbstractController +{ + + /** + * @var MetricsService The metrics service + */ + private MetricsService $metricsService; + + /** + * The constructor sets al needed variables. + * + * @param MetricsService $metricsService The metrics service + */ + public function __construct(MetricsService $metricsService) + { + $this->metricsService = $metricsService; + + }//end __construct() + + /** + * Provides a health check endpoint. + * + * @return Response + * + * @Route("/health-check", methods={"GET"}) + */ + public function metrics(): Response + { + $status = 200; + + // $metrics = $this->metricsService->getMetricsAsString(); + + return new Response(['status' => 'ok'], $status, ['Content-type' => 'text/plain']); + + }//end metrics() +}//end class From 3757906347d90226146ba8bf7b42830095ef6e5d Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Mon, 27 May 2024 18:34:34 +0200 Subject: [PATCH 2/4] Endpoint improvements --- Resources/config/routes.yaml | 5 ++ src/Controller/HealthController.php | 97 +++++++++++++++++++++++++++-- 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/Resources/config/routes.yaml b/Resources/config/routes.yaml index 4c7117a6..fd435153 100644 --- a/Resources/config/routes.yaml +++ b/Resources/config/routes.yaml @@ -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" diff --git a/src/Controller/HealthController.php b/src/Controller/HealthController.php index 0e75a893..442a77ca 100644 --- a/src/Controller/HealthController.php +++ b/src/Controller/HealthController.php @@ -5,9 +5,15 @@ 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. @@ -26,14 +32,28 @@ class HealthController extends AbstractController */ 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 */ - public function __construct(MetricsService $metricsService) + public function __construct(MetricsService $metricsService, ParameterBagInterface $parameters, EntityManagerInterface $entityManager) { $this->metricsService = $metricsService; + $this->parameters = $parameters; + $this->entityManager = $entityManager; }//end __construct() @@ -44,13 +64,80 @@ public function __construct(MetricsService $metricsService) * * @Route("/health-check", methods={"GET"}) */ - public function metrics(): Response + public function healthCheck(Request $request): Response { - $status = 200; + $acceptHeader = $request->headers->get('Accept') ?? 'application/json'; + + $status = 'pass'; + $outputMessage = null; + $responseStatusCode = 200; + $mongoDBCacheStatus = 'pass'; + + try { + $client = new Client(' '); + // Is this best way to check connection? + $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; + $message = 'ome database connections failed: ' . (string) $mongoDBFailCount . ' out of ' . (string) $mongoDBCount . ' connections'; + $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; + } + + $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 + ] + ] - // $metrics = $this->metricsService->getMetricsAsString(); + ] + ]; - return new Response(['status' => 'ok'], $status, ['Content-type' => 'text/plain']); + return new Response(json_encode($responseArray), $responseStatusCode, ['Content-Type' => $acceptHeader]); }//end metrics() }//end class From fc9cb14b4b2452a3d671fbe5f93841fde4182044 Mon Sep 17 00:00:00 2001 From: GitHub Actions <> Date: Mon, 27 May 2024 16:35:13 +0000 Subject: [PATCH 3/4] Update src from PHP Codesniffer --- src/Controller/HealthController.php | 57 +++++++++++++++-------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/Controller/HealthController.php b/src/Controller/HealthController.php index 442a77ca..48ee2b20 100644 --- a/src/Controller/HealthController.php +++ b/src/Controller/HealthController.php @@ -33,7 +33,7 @@ class HealthController extends AbstractController private MetricsService $metricsService; /** - * @var ParameterBagInterface The parameterbaginterface + * @var ParameterBagInterface The parameterbaginterface */ private ParameterBagInterface $parameterBagInterface; @@ -45,9 +45,9 @@ class HealthController extends AbstractController /** * The constructor sets al needed variables. * - * @param MetricsService $metricsService The metrics service - * @param ParameterBagInterface $parameters The Parameter bag - * @param EntityManagerInterface $entityManager The Parameter bag + * @param MetricsService $metricsService The metrics service + * @param ParameterBagInterface $parameters The Parameter bag + * @param EntityManagerInterface $entityManager The Parameter bag */ public function __construct(MetricsService $metricsService, ParameterBagInterface $parameters, EntityManagerInterface $entityManager) { @@ -66,10 +66,10 @@ public function __construct(MetricsService $metricsService, ParameterBagInterfac */ public function healthCheck(Request $request): Response { - $acceptHeader = $request->headers->get('Accept') ?? 'application/json'; + $acceptHeader = ($request->headers->get('Accept') ?? 'application/json'); - $status = 'pass'; - $outputMessage = null; + $status = 'pass'; + $outputMessage = null; $responseStatusCode = 200; $mongoDBCacheStatus = 'pass'; @@ -77,15 +77,15 @@ public function healthCheck(Request $request): Response $client = new Client(' '); // Is this best way to check connection? $client->listDatabases(); - } catch (Exception|MongoDBException $e) { + } catch (Exception | MongoDBException $e) { $mongoDBCacheStatus = 'fail'; - $status = 'fail'; - $outputMessage = 'The cache MongoDB connection failed: ' . $e->getMessage(); + $status = 'fail'; + $outputMessage = 'The cache MongoDB connection failed: '.$e->getMessage(); $responseStatusCode = 400; } - $objectDatabases = $this->entityManager->getRepository(Database::class)->findAll(); - $mongoDBCount = count($objectDatabases); + $objectDatabases = $this->entityManager->getRepository(Database::class)->findAll(); + $mongoDBCount = count($objectDatabases); $mongoDBPassCount = 0; $mongoDBFailCount = 0; @@ -94,8 +94,8 @@ public function healthCheck(Request $request): Response $client = new Client($database->getUri()); $client->listDatabases(); $mongoDBPassCount++; - } catch (Exception|MongoDBException $e) { - $mongoDBFailCount++; + } catch (Exception | MongoDBException $e) { + $mongoDBFailCount++; } } @@ -103,20 +103,21 @@ public function healthCheck(Request $request): Response if ($status !== 'fail') { $status = 'warn'; } + $responseStatusCode = 400; - $message = 'ome database connections failed: ' . (string) $mongoDBFailCount . ' out of ' . (string) $mongoDBCount . ' connections'; - $outputMessage = $outputMessage ? $outputMessage .= ' and s'.$message : $outputMessage = 'S' . $message; + $message = 'ome database connections failed: '.(string) $mongoDBFailCount.' out of '.(string) $mongoDBCount.' connections'; + $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(); + $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; } - + $responseArray = [ 'status' => $status, 'version' => '0.1.0', @@ -124,20 +125,20 @@ public function healthCheck(Request $request): Response 'notes' => [], 'output' => $outputMessage, 'checks' => [ - 'errors' => $errors, + 'errors' => $errors, 'mongodb' => [ - 'cache' => $mongoDBCacheStatus, + 'cache' => $mongoDBCacheStatus, 'otherConnections' => [ 'total' => $mongoDBCount, - 'pass' => $mongoDBPassCount, - 'fail' => $mongoDBFailCount - ] - ] + 'pass' => $mongoDBPassCount, + 'fail' => $mongoDBFailCount, + ], + ], - ] + ], ]; return new Response(json_encode($responseArray), $responseStatusCode, ['Content-Type' => $acceptHeader]); - }//end metrics() + }//end healthCheck() }//end class From 4d487a324bc299ba76d2019c37a8075d5752f6e6 Mon Sep 17 00:00:00 2001 From: Barry Brands Date: Tue, 28 May 2024 01:53:23 +0200 Subject: [PATCH 4/4] fix client --- src/Controller/HealthController.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Controller/HealthController.php b/src/Controller/HealthController.php index 48ee2b20..9755c87d 100644 --- a/src/Controller/HealthController.php +++ b/src/Controller/HealthController.php @@ -74,8 +74,7 @@ public function healthCheck(Request $request): Response $mongoDBCacheStatus = 'pass'; try { - $client = new Client(' '); - // Is this best way to check connection? + $client = new Client($this->parameters->get('cache_url')); $client->listDatabases(); } catch (Exception | MongoDBException $e) { $mongoDBCacheStatus = 'fail';